どうでもいいプログラム研究所

とある編集者によるIT、Web、ソフトウェア、プログラミングに関する雑記と覚え書き

PhotoshopとJavaScriptでフォルダ内の画像のサイズを一括変更する

f:id:tdyu5021:20191106014946p:plain

紙媒体、Web媒体問わず、制作業務を行っていると画像ファイルのサイズを変更する作業が多く発生します。これが面倒なので、JavaScriptを使ってPhotoshopで複数の画像サイズ変更を一発で行うスクリプトを作成しました。その方法を記します。

フォルダ内の画像のサイズを一括して変更するJavaScript

最初にコードを載せておきます。以下のコードをテキストエディタに貼り付け、JSファイルまたはJSXファイルとして保存したうえで、Photoshopの[ファイル]→[スクリプト]→[参照]からこのファイルを選択し実行すると処理が始まります。

(function(){
    
var arr = new Array();
arr = ["jpg","jpeg","png","gif","psd","bmp"];

//単位をピクセルに変更
preferences.rulerUnits=Units.PIXELS; 

//対象のフォルダを選択
var folderObj = Folder.selectDialog("フォルダを選択してください");
    if(folderObj===null){
        return;
    }

//幅を入力するダイアログを表示。数字以外入力できないようにする
var regex = false;
while(regex==false){
var n = prompt("幅を指定してください",1500);
var regex = new RegExp(/^[0-9]+$/);
regex = regex.test(n);  
    if(n===null){
        return;
    }
    if(!regex){
        alert("数字を入力してください");  
    }
}

//解像度を入力するダイアログを表示。数字以外入力できないようにする
var regex2 = false;
while(regex2==false){
var reso = prompt("解像度を入力してください",72);
var regex2 = new RegExp(/^[0-9]+$/);
regex2 = regex2.test(reso);  
    if(reso===null){
        return;
    }
    if(!regex2){
        alert("数字を入力してください");  
    }
}

//フォルダ内のファイル全部をフルパスで取得
var fileList = folderObj.getFiles();

for(var i = 0; i< fileList.length; i++){
    try{
        var fName = fileList[i].name;//ファイル名だけ取得
        var reg=/(.*)(?:\.([^.]+$))/;
        fName = fName.match(reg)[2];//拡張子だけ取得
    }catch(e){
            $.write("エラー" +'\n');
        }

    //拡張子を調べ、対象のファイルが画像以外ならスキップ
    fName = fName.toLowerCase();
    var isExist = checkExist(arr, fName);
    if(isExist==false){
        continue;
    }

    //ファイルを開く
    var fileObj = new File(fileList[i]);
    open(fileObj);
    var flg = fileObj.open("r");

    var ad = activeDocument;
    var x=ad.width; //開いたファイルの幅を取得
    var y=ad.height; //開いたファイルの高さを取得

    var newX;
    var newY;

    if(x>y){
        newX = parseInt(n);
        newY = (y * newX) / x;
    }else{
      newY = parseInt(n);
      newX = (x * newY) / y;
    }

    //リサイズする
    ad.resizeImage(newX, newY, reso, ResampleMethod.BICUBIC);
    ad.save();
    ad.close(SaveOptions.DONOTSAVECHANGES);
}
alert("完了しました");

})();

function checkExist(arr_, str){
    for(var i = 0; i<arr_.length; i++){
            if(str==arr_[i]){
                return true;
             }        
    }
    return false;
 }

内容としては次の通りです。

まずフォルダ選択ダイアログが表示されるので、任意のフォルダを選びます。その後、幅を指定するダイアログと解像度を指定するダイアログが現れますので、そこで指定したい数字を入力すると、先ほど選択したフォルダ内にある画像ファイルの長辺がすべて指定したピクセル数にサイズ変更され、すべて終わると「完了しました」というメッセージが表示されます。

この流れを実行したのが、以下のgif動画です。

f:id:tdyu5021:20191106020912g:plain

コードのポイントを解説

画像の単位を決める

まずサイズ変更するに当たり、1500pxにするのか、1500mmにするのか、単位を指定して置かなければなりません。今回はピクセルにします。単位をピクセルに指定する記述は以下です。

preferences.rulerUnits=Units.PIXELS;

サイズ変更するresizeImageメソッド

使いやすいようにいろいろ機能は足していますが、このスクリプトの大まかな流れは以下の通りです。

  1. フォルダ内のファイル名をすべて取得
  2. そのファイル名をもとにファイルを開く
  3. resizeImageメソッドでサイズを変更する
  4. ファイルを閉じる
  5. 上記の2-4をループ

その中でもコアとなるのが、画像をリサイズするresizeImageメソッドです。このメソッドは以下の引数を取ります。

f:id:tdyu5021:20191108232455p:plain

※このスクリプトを書いたときに知らなかったのですが、縦横比を固定にして拡大縮小したいときは、もう片方を"undifined"と書けば成り行きで変更されるそうです。私が今回作ったように、片方の辺の縮尺率に合わせてもう1辺のサイズをわざわざ記述する必要はないそうです。

画像ファイルだけ操作する

フォルダオブジェクトには、selectDialogメソッドという、選択ダイアログでフォルダを選ぶメソッドが存在します。まずはそれによってフォルダオブジェクトを生成します。その後、GetFilesメソッドでフォルダ内にあるファイル名の文字列をすべて取得します。ファイル名は配列で取得されます。

そのファイル名を利用してファイルオブジェクトを生成し、各ファイルのリサイズ処理をループさせます。ただフォルダに画像フォルダがなかったり違うファイルがあるとエラーになってしまうので、「画像ファイルが含まれているか」を調べる記述を書きました。それがコード内のcheckExistという関数です。

それを判定するロジックとしては、あらかじめ画像ファイルの拡張子を配列に入れておき、対象のファイル名の拡張子がその配列内拡張子に合致すればリサイズし、そうでなければ処理をスキップ(Continue)します。

なお、ファイルが画像ファイルであるかどうかを判定するには、ファイル名から拡張子を抜き出す記述が必要ですが、Qiitaにピッタリの記事があったので、ありがたく拝借しました。

qiita.com

画像が縦長か横長かを判断する

今回のスクリプトでは、縦長画像だったら天地を指定したサイズに、横長だったら左右を指定したサイズにするというスクリプトにしています。

これについては、特に難しいことはなく、開いたファイルオブジェクトに対して、widthプロパティ、heightプロパティで天地左右それぞれの値を調べて比較し、その大小で処理を分岐するif文を書いているだけです。

ざっくり要点だけ説明すると以上になります。記述数も少なく、割と汎用的に使えるスクリプトではないかなと思っています。