※2015/09/06 記事修正・追加
@moko_03_25さんがお書きになった『BISHAMON ゲームエフェクトデザイン入門』の付録?の連番画像を並べてくれるPhotoshopのスクリプトがあります。( o_s_t(@mmb_jp)さんがお作りになったそうです )
ここしばらくはエフェクト制作の作業などをしてるんですが、
SIやAEから書きだした連番の画像を1枚のテクスチャにしてUVアニメで使おうと思ったときに
8枚くらいまでならそんなに手間じゃないですが枚数多いと手動で並べるのがめんどくさいです。
Photoshopのコンタクトシート2という最初から入ってるスクリプト(勝手にサイズ変えやがる…)とか、
あとフリーのShoeboxというアトラス化(ある程度キレイに並べてくれるけど順番バラバラ…)とか試してみていて、もう自分でスクリプト書くしかないかと思ったときにBISHAMON本のスクリプトのことを思い出して使わせて頂きました!
しかし…
何回か使わせてもらっていて気づいたのですが、
並べる画像が透過などないモノなら問題なく並べてくれますが、
アルファ抜き(透明部分)がある画像(主にpng?)の場合に
あのスクリプトのなかで行われている処理(画像を読み込んで全選択してコピー、
新しいドキュメントにペーストして移動)のコピペが
透明部分を考慮しない最小のサイズとしてペーストされてしまい
最終的な並びの位置がズレてしまっていました。
例えば、下の画像の左側の画像を読み込ませた場合に
ペーストされた後は右側の画像のように最小のサイズで扱われます。
それを最後にまた手動で並べ直すのも面倒なのでスクリプトの方を勝手に触らせてもらいました。 でも二次配布などはダメなので修正した部分だけを書いておきます。
※追記↓
mokoさんにこの記事の件をご確認したところ、
o_s_tさん と秀和システム さん にもご確認して頂き、
正式にOKが頂けたのでスクリプトのソースと配布リンクを書かせて頂きます。
この場を借りましてご了承頂いたmoko様、o_s_t様、秀和システム様にお礼申し上げます。
ちなみにまだ「BISHAMON ゲームエフェクトデザイン入門」をお持ちでない方は
秀和システム
さん のサイトから目次などご確認頂けます。
タイトルの通りBISHAMONに関する本ではありますが、
BISHAMONを使わない場合のエフェクト制作の参考にもなる良本だと思います!
BISHAMON ゲームエフェクトデザイン入門|書籍情報|秀和システム
http://www.shuwasystem.co.jp/products/7980html/4118.html
o_s_tさんが書かれた元のスクリプトの処理が良いので大きな修正は行っていませんが、
変更させてもらったのはloadAsSmartObjという関数(スクリプトリスナーからコピペ)を作って
読み込む画像をスマートオブジェクト化している点です。
こうすることでアルファ抜き(透明部分)がある画像でもサイズが維持されたまま移動されます。
また、処理を同じにするためにコメントアウトしていますが、
もしレイヤー名に拡張子をつけなくしたい場合はテキストエディタ等で125行目の//を消して下さい。
この改造版のスクリプトをご利用になる場合はこちらからどうぞ。
私の方で改造した部分について何かありましたらご連絡下さい。
================================================
/* SerialImageLayout.jsx 2013.12.17 o_s_t 連番テクスチャを1枚のドキュメントに並べるスクリプトです。 【使い方】 1.ファイル選択ダイアログから任意の連番テクスチャ中の1枚を選択。 1枚は連番中の何番目でも良い。ファイル名の末尾が数字になっている事。 連番はファイル名順になるのでパディングは必要。 2.ファイルを選択後、横並び枚数設定のダイアログが開くので、 横に並べたい枚数を入力。デフォルトでは連番の最大数が入っているので、 1以上デフォルト値以下の値を入力する 3.新規ドキュメントに連番テクスチャがレイアウトされる。各ファイルは レイヤーとして保持され、レイヤー名はファイル名を引き継ぐ。 レイアウトは1枚目の縦横サイズを基準にするので、他サイズの画像が 混ざっていると正しくレイアウトされないので注意。 画像そのものは正方形でなくても正しく配置される。 */ /* 2015.09.06 redglasses67 許可を頂き、o_s_tさんが書かれたスクリプトの一部を改造させて頂きました。 使い方や基本的な処理は変えていません。 今までの処理ですと 1.画像を読み込んで全選択し、コピー 2.新しいドキュメントにペーストしてそれを移動 という感じでしたが、 アルファ抜き(透明部分)がある画像(主にpng?)の場合に 透明部分を考慮しない最小のサイズとしてペーストされてしまい 最終的な並びの位置がズレてしまっていました。 なので、画像を読み込む部分の処理を ドラッグ&ドロップしたのと同じスマートオブジェクト化する方法にしました。 こうすることで読み込まれた後もサイズが変更されずに配置されます。 ※コメントアウトの頭に「----------」がついている箇所が変更した部分です。 */ //基準となるファイルの選択 OriginPath = File.openDialog("連番画像ファイルを選択してください"); if (OriginPath) { //選択ファイルから各種情報を取得 fileObj = new File(OriginPath); baseName = fileObj.fsName.replace(/(^.*\\)/g,""); SerchName = baseName.replace(/([0-9]*\..*)+$/g,"*"); FolderPath = fileObj.fsName.replace(/([^\\]*$)/g,""); FolderObj = new Folder(FolderPath); //フォルダ内の連番画像を収集 FileName = FolderObj.getFiles(SerchName); FileNumber = FileName.length; if (FileNumber > 0) { //最初の画像を読み込み、縦横サイズを取得 ActiveDoc = app.open(FileName[0]); FileWidth = activeDocument.width.value; FileHeight = activeDocument.height.value; //横並び枚数指定ダイアログ DigWin = new Window("dialog","横並び枚数を指定",[280,220,280+245,220+75]); DigWin.sText = DigWin.add("statictext",[20,12,160,40],"横に並べるテクスチャ枚数:"); DigWin.eText = DigWin.add("edittext",[160,10,224,30], FileNumber); DigWin.okBtn = DigWin.add("button",[20,40,225,65], "OK", {name:"ok"}); //----------入力しやすいようにedittext部分をアクティブにする DigWin.eText.active = true; //実行処理 DigWin.okBtn.onClick = function() { //ダイアログのパラメータを取得 WidthNum = eval(DigWin.eText.text); this.parent.close( false ); if ((WidthNum > 0) && (WidthNum <= FileNumber)) { //新規ドキュメントを作成 HeightNum = Math.ceil(FileNumber / WidthNum); NewDocW = FileWidth * WidthNum; NewDocH = FileHeight * HeightNum; preferences.rulerUnits = Units.PIXELS; NewDoc = documents.add(NewDocW,NewDocH); //基準ファイルを一旦削除 activeDocument = ActiveDoc; activeDocument.close(SaveOptions.DONOTSAVECHANGES); //配置時のオフセット値決定 OffsetX = Math.floor((NewDocW / -2) + (FileWidth / 2)); OffsetY = Math.floor((NewDocH / -2) + (FileHeight / 2)); //連番画像を開き、新規ドキュメントに複製レイアウトする var Num = 0; //----------レイヤー名にする文字列を入れる変数 var layerName; for (Y=0; Y < HeightNum; Y++) { for(X=0; X < WidthNum; X++) { if (Num <= FileNumber -1) { //----------引数にファイルのパスを渡し、スマートオブジェクトとして読み込む loadAsSmartObj(FileName[Num]); /*----------読み込んでコピー&ペーストの部分はコメントアウト ActiveDoc = app.open(FileName[Num]); activeDocument = ActiveDoc; DocName = activeDocument.name; activeDocument.selection.selectAll(); activeDocument.activeLayer.copy(); activeDocument.close(SaveOptions.DONOTSAVECHANGES); activeDocument = NewDoc; activeDocument.paste(); */ activeDocument.activeLayer.translate(OffsetX+(FileWidth * X),OffsetY+(FileHeight * Y)); //----------読み込んだ画像のフルパスからファイル名を取得し、変数に入れる layerName = FileName[Num].fsName.replace(/(^.*\\)/g,""); //----------拡張子を取り除く処理。レイヤー名から拡張子を消したい場合はコメントアウトを外して下さい //layerName = layerName.match(/(.+)(\.[^.]+$)/)[1]; //----------レイヤーの名前を読み込んだファイル名に変更 activeDocument.artLayers[0].name = layerName; Num = Num + 1; } } } //----------最後に全てラスタライズして普通のレイヤーに。スマートオブジェクトのままが良い場合はコメントアウトして下さい activeDocument.rasterizeAllLayers(); }else{ //エラー処理。横並び数が不正 alert("正しい数値を入力してください"); ActiveDoc.close(SaveOptions.DONOTSAVECHANGES); } } //ダイアログの表示 DigWin.show(); }else{ //エラー処理。画像ファイルがフォルダにない alert("ファイルが見つかりません"); } } //----------以下追加した処理。基本的にはScriptListenerからコピペ //----------画像をドラッグ&ドロップした時と同じで読み込んだ画像をスマートオブジェクトにします。 function loadAsSmartObj(filePath){ var idPlc = charIDToTypeID( "Plc " ); var desc2 = new ActionDescriptor(); var idnull = charIDToTypeID( "null" ); desc2.putPath( idnull, new File( filePath ) ); var idFTcs = charIDToTypeID( "FTcs" ); var idQCSt = charIDToTypeID( "QCSt" ); var idQcsa = charIDToTypeID( "Qcsa" ); desc2.putEnumerated( idFTcs, idQCSt, idQcsa ); var idOfst = charIDToTypeID( "Ofst" ); var desc3 = new ActionDescriptor(); var idPxl = charIDToTypeID( "#Pxl" ); var idHrzn = charIDToTypeID( "Hrzn" ); desc3.putUnitDouble( idHrzn, idPxl, 0.000000 ); var idVrtc = charIDToTypeID( "Vrtc" ); desc3.putUnitDouble( idVrtc, idPxl, 0.000000 ); desc2.putObject( idOfst, idOfst, desc3 ); executeAction( idPlc, desc2, DialogModes.NO ); } /* filename = File.openDialog("開く画像ファイルを指定してください"); if (filename) { fileObj = new File(filename); app.open(fileObj); alert("ファイルパスは"+fileObj+"です"); FileName = fileObj.fsName.replace(/(^.*\\)/g,""); SerchName = FileName.replace(/([0-9]*\..*)+$/g,"*"); FolderPath = fileObj.fsName.replace(/([^\\]*$)/g,""); alert("ファイル名は"+FileName+"です"); alert("検索名は"+SerchName+"です"); alert("フォルダパスは"+FolderPath+"です"); } */
=================================================
コメントをお書きください
Floretta Levens (火曜日, 24 1月 2017 23:49)
It's very trouble-free to find out any matter on net as compared to books, as I found this article at this site.
A (土曜日, 06 2月 2021 21:02)
連番画像(読み込まれるテクスチャ)の解像度が"72"以外だと、アトラス化された一枚のテクスチャに対して、表示される連番画像の大きさが解像度に比例して変わってしまうので、
(FileHeight = activeDocument.height.value; の下の行に)
FileResolution = activeDocument.resolution;
(NewDoc = documents.add(NewDocW,NewDocH)) の下の行に)
activeDocument.resizeImage(undefined, undefined, FileResolution, ResampleMethod.NONE, 0);
をそれぞれ追加すると
連番画像と結果のアトラステクスチャの解像度が一致し、大きさの問題もなくなると思います。
間違っていたら申し訳ありません...