jsxでレイヤーの名前で保存する


まえがき

500~1000個の画像データ生成作業をアセットやアクションでは処理できない内容のため手作業を考えた時・・・
「このままでは終わらないよぉ」 !!(@_@;
と思って書いたjsxで学んだ事のメモです。

サンプルPSDに関して

同じ背景にレイヤーをかえることで数種類の画像データを生成する。
いか、psdの中身です。

このpsdから"Other_01~05" + "_10~100000"という命名規則で以下のような名前でGIF画像を合計40ファイルほど生成する。

  • Other_01レイヤーのGIF画像の種類
    "Other_01_100000.gif" "Other_01_50000.gif" "Other_01_10000.gif" "Other_01_5000.gif" "Other_01_1000.gif" "Other_01_100.gif" "Other_01_50.gif" "Other_01_10.gif"

  • Other_02レイヤーのGIF画像の種類
    "Other_02_100000.gif" "Other_02_50000.gif" "Other_02_10000.gif" "Other_02_5000.gif" "Other_02_1000.gif" "Other_02_100.gif" "Other_02_50.gif" "Other_01_10.gif"

  • Other_03レイヤーのGIF画像の種類
    "Other_03_100000.gif" "Other_03_50000.gif" "Other_03_10000.gif" "Other_03_5000.gif" "Other_03_1000.gif" "Other_03_100.gif" "Other_03_50.gif" "Other_01_10.gif"・・・・

生成する画像全てに必要となる背景のレイヤーには"base"と付けました。
更に数字の種類別で例えば、"*_50.gif"の各画像では"Other_01"~"Other_05"のレイヤー分、"50"という文字のレイヤーと"50_waku"の枠のレイヤーがつく、"Other_01~05"のレイヤーで5種類の画像を書き出す動作を考えます。

以下、完成画像のフォルダ内のスクショ。

手順

処理の内容を把握する

この段階はscriptを書きながら考えている処理の順番を具体的にイメージするので、日々の経験が役に立ちます。

  1. PSDの中で必要なレイヤーを表示させる
  2. 適切な圧縮形式を選択(オプションを付ける場合もある)
  3. 命名規則がありそれに沿って画像名を指定して保存

必要な処理を選定する

今回は前の段階で上げた処理を以下のように考えました

1 PSDの中で必要なレイヤーを表示させる

  • for文で全てのレイヤーを見通す
  • if文で表示の有無をひも付ける

2 適切な圧縮形式を選択(オプションを付ける場合もある)

  • 今までの圧縮形式を確認
  • (保存時に適切なオプションをつける)

3 命名規則がありそれに沿って画像名を指定して保存

  • 命名規則にそってレイヤーに名前をつける
  • 生成された画像名をレイヤーの名前を活かす事で命名規則にそぐわせる

処理内容を落とし込む

実際に設定した(これからする)関数等の指定ははしょって、具体的にスクリプトに落とし込みます。

【1step】必要なカテゴリ分のfor文を用意
  ↓
【2step】レイヤー全てを見るfor文を用意
  ↓
【3step】レイヤーの数だけレイヤーの内容を見るので、さらにレイヤーの数の回数見る事が出来るfor文で囲う
  ↓
【4step】 保存のタイミングは1周りレイヤーを見て回った後に実行

JSX
function getLayerObj(){ 
    //レイヤーの情報を整理する関数を準備
    var layers = activeDocument.layers;
    var layerCount = 0;
    var layerMax = layers.length;
        ・    
        ・    
        ・    
        ・    
    //保存形式の準備、減色などの調節
    var gifOpt = new GIFSaveOptions();
        gifOpt.colors = 64;
        gifOpt.dither = Dither.NONE;
        gifOpt.matte = MatteType.WHITE;
        ・    
        ・    
        ・    

/*------------------------------------------------------------------------
【1step】
必要なカテゴリ分のfor文を用意
・保存する種類分の回数を回すfor文
・ここではサンプルpsdの 100000,50000,10000,5000,1000,100,50,10 を種類として、
 すべてのレイヤーを解析する回数を8回指定。
------------------------------------------------------------------------*/
    for (var m = 0 ; m < 8; m++){
        wakuLayer = sizeNum[m] + "_waku";
/*------------------------------------------------------------------------
【3step】
レイヤーの数だけレイヤーの内容を見るので、
さらにレイヤーの数の回数見る事が出来るfor文で囲う
------------------------------------------------------------------------*/
        for(var n = 0; n<layerMax; n++){
/*------------------------------------------------------------------------
【2step】
レイヤー全てを見るfor文を用意
------------------------------------------------------------------------*/
            for(var i = 0; i<layerMax; i++){
                   //表示させるレイヤーをif文でふるい分け
                   if(i == n){
                       //レイヤーの名前取得
                       fName = layers[i].name;
                       //保存するパスの生成。ここで、ファイル名は命名規則にそぐうものを生成させるようにする。
                       fileGifObj = new File( path + fName + "_" + sizeNum[m] +".gif" );
                          //表示させるレイヤーを変数に格納
                          visibleLayer03 = activeDocument.layers[i];
                            ・
                            ・
                            ・
                            ・
                            ・
                            ・
                        }else{
                          //表示させないレイヤーにはそのまま非表示のBooleanを渡す
                          activeDocument.layers[i].visible = false;
                        }
                    }
             //全部のレイヤーから保存しないレイヤーの場合はフラグを立てる 
             if(fName == "base"){
                    noPrintLayerFlag = true;
                    }
                        for (var l = 0 ; l < 8; l++){
                               ・
                               ・
                               ・
                            }
/*------------------------------------------------------------------------
【4step】
 保存のタイミングは1周りレイヤーを見て回った後に実行
・レイヤーの名前が保存対象外だったら保存しない。"base"とかです。
------------------------------------------------------------------------*/
                if(!noPrintLayerFlag){
                    //レイヤーを表示Boolean。保存メゾットでデータ格納する
                    visibleLayer01.visible = true;
                    visibleLayer02.visible = true;
                    visibleLayer03.visible = true;
                    visibleLayer04.visible = true;
                    activeDocument.saveAs( fileGifObj, gifOpt, true, Extension.LOWERCASE);
                    }else{
                        //フラグを戻す
                        noPrintLayerFlag = false;
                    }
                } 
            } 
             alert("おわったよ!"); 
       }
      //スクリプトを実行 
      getLayerObj();

実際のソースはこちら
https://gist.githubusercontent.com/tomoka/ac0a2e7db377043aaf83/raw/69073871dcdbf60cb714381eeb04b6b6ccdf96f8/getLayerObj.jsx

あとがき

jsxのお陰で、それほど苦労もなく書き出す事が出来ました。数が多いと待ち時間が伸びるのがネックですが、確実に画像を生成してくれるので漏れも少なくなります。つくづくjsxが便利だとおもった。
このjsxは汎用性が低いので、次書く時はそのときの作業だけでなく汎用性の高いjsxがかけるようにがんばる。