ただの備忘記録

忘れないように記録を残します。忘れるから記録に残してます。そして、その記録が役立つといいかな。

【Photoshop JSX Script】ファイル変換

2015年05月08日 | JavaScript

【基本機能】
Photoshopのスクリプトを使って、フォルダ内のファイルを一括変換します。

読み込めるファイル(変換前のファイル)はフォルダ内の全ファイル、もしくは拡張子で指定したファイルに制限することができます。
出力設定はpsd、jpg、pngの3形式に対応しています。

【スクリプトの準備】

ソースに記述したスクリプトをテキストファイルに貼り付け、ファイル名を「ファイル変換.jsx」として保存します。
「psd→jpg変換.jsx」としても分かりやすいです。拡張子さえ変更しなければ、ファイル名は自由に付けてください。
Photoshopが入っていないと起動しません。

【起動方法】
その1:スクリプトを呼び出してから開くダイアログでフォルダを選択します。
その2:処理したいフォルダにあるファイルを1つ開いてからスクリプトを実行すると、そのフォルダを選択したことになります。

【設定変更】
現在はPSD形式からJPEG形式への変換設定になっています。
fe1とfe2を変更することで処理ファイルの対象を変更できます。その他、出力の細かな設定は「保存オプションの設定」で行ってください。

【ソース】

//ファイル変換
#target photoshop

//設定項目(psd,jpg,png)
fileExp = new Array("*","psd","jpg","png");
fe1 = 1; //変換前の拡張子
fe2 = 2; //変換後の拡張子

//保存オプションの設定
if (fe2 == 1) {
    //PSD
    var saveOpt = new PhotoshopSaveOptions;
    saveOpt.alphaChannels = true; //αチャンネルを保存
    saveOpt.annotations = true; //注釈
    saveOpt.embedColorProfile = true; //カラープロファイルを保存
    saveOpt.layers = true; //レイヤー保存
    saveOpt.spotColors = true; //スポットカラー保存
} else if (fe2 == 2) {
    //JPEG
    var saveOpt = new JPEGSaveOptions();
    saveOpt.embedColorProfile = true; //カラープロファイルを保存
    saveOpt.quality = 10; //品質:0~12(12が最高画質)
    saveOpt.formatOptions = FormatOptions.STANDARDBASELINE //ベースライン(標準)
    //saveOpt.formatOptions = FormatOptions.OPTIMIZEDBASELINE; //ベースライン(最適化)
    //saveOpt.formatOptions = FormatOptions.PROGRESSIVE; //プログレッシブ
    //saveOpt.scans = 3; //プログレッシブ時のスキャン数:3~5
    saveOpt.matte = MatteType.NONE;
} else if (fe2 == 3) {
    //PNG
    saveOpt = new PNGSaveOptions();
    saveOpt.interlaced = false; //インターレース
}

selFolder();

//フォルダを選択
function selFolder() {
    var n = documents.length; //開いているデータの数
    if (n > 0) {
        //アクティブドキュメントのパスを取得
        var folderPath = activeDocument.path;
        var folderObj = new Folder(folderPath);
    } else {
        //ダイアログの表示
        var folderObj = Folder.selectDialog("フォルダを選択してください。");
    }

    //フォルダの確認
    if (folderObj) {
        //全てのファイル
        fileList = folderObj.getFiles("*." + fileExp[fe1]); //ファイルはアルファベット順になっている
        //alert(fileList.length+"個のファイルがあります");
        
        //フォルダ名をデコード
        pathName = decodeURIComponent(folderObj.name);
        
        //ファイル数の取得
        edPage = fileList.length;
        
        //ファイル数の確認
        if (edPage > 0) {
            //開始ファイルと終了ファイル
            stPage = 1;
            stFile = decodeURI(fileList[stPage-1].name);
            edFile = decodeURI(fileList[edPage-1].name);
        
            //ダイアログ初期化
            var newDialog = new createDialog_DLG();
            initializeBuilder(newDialog);

            //処理したファイル名のリスト
            text_fileNames = "";

            //ダイアログ表示
            if(runBuilder(newDialog)){
                with(newDialog){
                    //ページ番号取得
                    //stPage = parseInt(pnl.start_page.text,10);
                    //edPage =parseInt(pnl.end_page.text,10);
                }
        
                for (var i=stPage-1; i < fileList.length; i++) {
                    var doc = fileList[i];
                    //ファイルを開く
                    open(doc);
                    //カラーモード確認
                    fileConvert(doc);
                }
            }

            //結果報告
            if (text_fileNames != "") {
                alert(text_fileNames);
            }
        } else {
            alert("処理対象のファイルが見つかりません。");
        }
    }
}

//ダイアログ(一括変換処理)
function createDialog_DLG(){
    var dialogResource = "dialog { text:'一括変換処理', bounds:[0, 0, 260, 200], ";
    dialogResource += " pnl: Panel { text:'フォルダ情報', bounds:[15, 8, 245, 136], ";
    dialogResource += " str: StaticText { text:'フォルダ:', bounds:[10, 23, 90, 36],  }, ";
    dialogResource += " str: StaticText { text:'" + pathName + "', bounds:[60, 23, 220, 41],  }, ";
    dialogResource += " start_file: StaticText { text:'" + stFile + "', bounds:[110, 57, 220, 70],  }, ";
    dialogResource += " str: StaticText { text:'開始:', bounds:[20, 57, 90, 70],  }, ";
    dialogResource += " start_page: EditText { bounds:[60, 57, 100, 75],  }, ";
    dialogResource += " end_file: StaticText { text:'" + edFile + "', bounds:[110, 90, 220, 103],  }, ";
    dialogResource += " str: StaticText { text:'終了:', bounds:[20, 90, 90, 103],  }, ";
    dialogResource += " end_page: EditText { bounds:[60, 90, 100, 108],  }, ";
    dialogResource += " }," ;
    dialogResource += " cancel: Button { text:'キャンセル', bounds:[50, 158, 112, 182],  }, ";
    dialogResource += " running: Button { text:'実行', bounds:[150, 158, 212, 182],  }, ";
    dialogResource += " }";

    var dlg = new Window( dialogResource );
    dlg.center();
    return dlg;
}
// ダイアログ(動作設定)=============================
function initializeBuilder(builder){
    with(builder){
        //ページ番号チェック
        function pageCheck() {
            stPage = parseInt(pnl.start_page.text,10)
            edPage = parseInt(pnl.end_page.text,10);
            //数値以外の場合
            if (isNaN(stPage)) {stPage = 1;}
            if (isNaN(edPage)) {edPage = fileList.length;}
            //大小が逆の場合、入れ替え
            if (stPage > edPage) {
                var n = stPage;
                stPage = edPage;
                edPage = n;
            }
            //最小値と最大値
            if (stPage < 1) {stPage = 1;}
            if (edPage > fileList.length) {edPage = fileList.length;}
            //表示変更
            pnl.start_page.text = stPage;
            pnl.end_page.text = edPage;
            pnl.start_file.text = decodeURI(fileList[stPage-1].name);
            pnl.end_file.text = decodeURI(fileList[edPage-1].name);
        }
    
        //初期値
        pnl.start_page.text = stPage;
        pnl.end_page.text = edPage;
        
        //ボタンイベント
        cancel.onClick = function(){ this.parent.close( false ); };
        running.onClick = function(){ this.parent.close( true ); };
        //ファイル名変更
        pnl.start_page.onChange = function() {pageCheck();};
        pnl.end_page.onChange = function() {pageCheck();};
    }
}

// ダイアログ(起動・実行)===================================================
function runBuilder(builder){
  return builder.show();
}

function fileConvert(builder) {
    //アクティブドキュメントを取得
    var doc = activeDocument;
 
    //パス取得
    var docPath = doc.fullName.fsName.toString();
    docPath = docPath.substring(0,docPath.lastIndexOf("\\")+1);
    //alert(docPath);

    //ファイル名取得
    var docOldName = doc.name;
    var docName = docOldName.substring(0,docOldName.lastIndexOf("."));
    
    //元データが2階調の場合
    if ((fe2 == 1) || (fe2 == 2)) {
        if (doc.mode == DocumentMode.BITMAP) {
            doc.changeMode(ChangeMode.GRAYSCALE);
        }
    }

    //別名保存の設定
    var docNewName = docName + "." + fileExp[fe2]
    var saveFileObj = new File(docPath + docNewName);
    
    //別名で保存
    try {
        activeDocument.saveAs(saveFileObj, saveOpt, true, Extension.LOWERCASE);
        //記録
        text_fileNames += docOldName + " → " + docNewName + "\n";
        //ファイルを閉じる
        activeDocument.close(SaveOptions.DONOTSAVECHANGES);
    } catch(msg) {
        alert(msg + " Can't save it.");
    }
}