Amazonで商品を見るセール会場へ

Photoshopでフォルダー内のPSDをJPG・PNGに一括出力するJSX|保存先・上書き・縮小

PhotoshopでPSDを開いて合成画像を出力する場合は、入力フォルダーを列挙し、各PSDを開く・書き出す・元PSDを保存せず閉じる処理をJSXで組み合わせます。保存先と形式、縮小の条件を先に決めると、出力結果を照合できます。

この処理はPSDごとに1枚の画像を作る用途です。レイヤー単位はレイヤーを個別ファイルに書き出す方法、カンプ単位はレイヤーカンプの書き出しを使います。Photoshopを使わず階層内の保存済み合成画像を変換する方法は、ImageMagickの記事で説明しています。

2026年10月19日に、Photoshop 2026(27.11.0)とWindows 11 Proで記事のコードを実行し、結果を「Photoshop 2026で実行した結果」に足しました。

目次

入力と出力を先に決める

作業用にPSDを複製し、入力用と出力用のフォルダーを分けます。最初は2〜3ファイルで確認し、RGB・8bit、透明な部分があるPSD、縮小が必要な縦長・横長のPSDを含めます。既にPhotoshopで開いているPSDは、この例では処理対象から外します。

設定 この例の処理
対象 選択フォルダー直下の .psd。拡張子の大文字も含む
出力 各PSDの合成画像をPNGまたはJPEGにする
保存先 入力と別のフォルダー。サブフォルダーの再帰処理はしない
同じ名前の画像 既存の出力を見つけたファイルはスキップする
開いているPSD ファイルのパスを照合してスキップする
色・ビット深度 RGB・8bitのみ。自動で色モードやビット深度を変更しない
縮小 上限を指定したときだけ長辺を縮小し、縦横比を維持する

出力フォルダーはこの処理専用にします。書き出し直前にも存在を確認しますが、他のプログラムによる同時書き込みまで防ぐ仕組みではありません。ファイル名の大文字・小文字やフォルダーへの別名参照がある場合も、複製した入力で確認してください。

スポンサーリンク

実行するファイル名と設定

下のコードを CGM_ExportFolderReview.jsx として保存し、先頭の2項目を編集します。初回は OUTPUT_FORMAT = "PNG"、MAX_LONG_EDGE = 0 のまま試します。

設定値 意味
OUTPUT_FORMAT = "PNG" PNG-24と透明度を指定する
OUTPUT_FORMAT = "JPEG" JPEG、品質100を指定する。透明度は保持しない
MAX_LONG_EDGE = 0 元の寸法を維持する
MAX_LONG_EDGE = 1000 長辺が1000pxを超える画像だけ縮小する

コードはICCプロファイルの埋め込みを指定していますが、sRGBへの変換処理は含めていません。JPEGの透明部分の背景や色の見え方は、出力画像を開いて確認します。納品にsRGBや特定の背景色が必要な場合は、入力をその条件に整えてから試してください。

キャンセル・既存ファイル・失敗を扱うコード

今回のコードは制御の流れを見直した確認用の例です。

2026年10月19日にPhotoshop 2026(27.11.0)とWindows 11 Proで実行し、PNGとJPEGの書き出し、長辺の縮小、既存の画像があるときのスキップ、CMYKのPSDのエラーを確かめました(結果は後の「Photoshop 2026で実行した結果」にまとめています)。

自分の画像で使う前に、複製したPSDで形式・透明度・色・寸法を確かめてください。

#target photoshop
// PNG or JPEG. 0 keeps the size; 1000 limits the long edge to 1000 px.
var OUTPUT_FORMAT = "PNG";
var MAX_LONG_EDGE = 0;
(function () {
    if (OUTPUT_FORMAT != "PNG" && OUTPUT_FORMAT != "JPEG") {
        alert("OUTPUT_FORMAT must be PNG or JPEG."); return;
    }
    if (MAX_LONG_EDGE < 0 || !isFinite(MAX_LONG_EDGE)) {
        alert("MAX_LONG_EDGE must be zero or positive."); return;
    }
    var source = Folder.selectDialog("Select the input PSD folder");
    if (!source) return;
    var destination = Folder.selectDialog("Select a separate output folder");
    if (!destination) return;
    function key(path) { return String(path).replace(/\\/g, "/").toLowerCase(); }
    if (key(source.fsName) == key(destination.fsName)) {
        alert("Use separate input and output folders."); return;
    }
    var files = source.getFiles(function (file) {
        return file instanceof File && /\.psd$/i.test(file.name);
    });
    if (!files.length) { alert("No PSD files in this folder."); return; }
    var originalActive = app.documents.length ? app.activeDocument : null;
    var oldUnits = app.preferences.rulerUnits;
    var oldDialogs = app.displayDialogs;
    var completed = 0, skipped = 0, failed = 0, notes = [];
    function isAlreadyOpen(file) {
        for (var i = 0; i < app.documents.length; i++) {
            try {
                if (key(app.documents[i].fullName.fsName) == key(file.fsName)) return true;
            } catch (unsavedDocument) {}
        }
        return false;
    }
    try {
        app.preferences.rulerUnits = Units.PIXELS;
        app.displayDialogs = DialogModes.NO;
        for (var n = 0; n < files.length; n++) {
            var input = files[n], document = null;
            var base = File.decode(input.name).replace(/\.psd$/i, "");
            var output = new File(destination.fsName + "/" + base +
                (OUTPUT_FORMAT == "PNG" ? ".png" : ".jpg"));
            if (output.exists || isAlreadyOpen(input)) {
                skipped++; notes.push("SKIP: " + base + " (existing output or open PSD)");
                continue;
            }
            try {
                document = app.open(input);
                if (document.mode != DocumentMode.RGB ||
                    document.bitsPerChannel != BitsPerChannelType.EIGHT) {
                    throw new Error("This example accepts RGB/8-bit PSD only.");
                }
                var width = document.width.as("px"), height = document.height.as("px");
                if (MAX_LONG_EDGE > 0 && Math.max(width, height) > MAX_LONG_EDGE) {
                    if (width >= height) {
                        document.resizeImage(UnitValue(MAX_LONG_EDGE, "px"), undefined,
                            undefined, ResampleMethod.BICUBIC);
                    } else {
                        document.resizeImage(undefined, UnitValue(MAX_LONG_EDGE, "px"),
                            undefined, ResampleMethod.BICUBIC);
                    }
                }
                var options = new ExportOptionsSaveForWeb();
                options.format = OUTPUT_FORMAT == "PNG" ? SaveDocumentType.PNG : SaveDocumentType.JPEG;
                options.PNG8 = false;
                options.transparency = OUTPUT_FORMAT == "PNG";
                options.interlaced = false;
                options.includeProfile = true;
                options.quality = 100;
                // Recheck immediately before export; use the folder for this process only.
                if (output.exists) throw new Error("Output appeared during processing.");
                document.exportDocument(output, ExportType.SAVEFORWEB, options);
                if (!output.exists || output.length === 0) throw new Error("Output file was not confirmed.");
                completed++; notes.push("OK: " + base);
            } catch (error) {
                failed++; notes.push("ERROR: " + base + " / " + error.message);
            } finally {
                if (document) {
                    try { document.close(SaveOptions.DONOTSAVECHANGES); }
                    catch (closeError) { notes.push("CLOSE ERROR: " + base + " / " + closeError.message); }
                }
            }
        }
    } finally {
        app.preferences.rulerUnits = oldUnits;
        app.displayDialogs = oldDialogs;
        if (originalActive) {
            try { app.activeDocument = originalActive; } catch (closedByUser) {}
        }
    }
    alert("Output: " + completed + " / Skip: " + skipped + " / Error: " + failed +
        "\n" + notes.join("\n"));
})();

入力または出力フォルダーの選択をキャンセルした場合は、画像を開く前に終了します。処理中に1ファイルでエラーが出ても次へ進み、開いたPSDは元ファイルを保存せず閉じる構成です。単位とダイアログ設定は最後に戻します。閉じる処理自体が失敗した場合は結果表示の CLOSE ERROR を確認し、開いたままのPSDを調べます。

出力数はファイルの存在とサイズが0より大きいことを確認した数です。画像の内容が正しいことを保証する数ではありません。エラー時に不完全な新規画像が残る場合は、結果表示と実ファイルを照合し、次の実行で既存ファイルとしてスキップされた理由を確認します。

Photoshopから実行する手順

  1. 作業中の画像を保存し、処理用に複製したPSD以外が書き換わらない状態を確認します。
  2. [ファイル]→[スクリプト]→[参照]から CGM_ExportFolderReview.jsx を選びます。
  3. 入力用のPSDフォルダーを選び、続いて別の出力フォルダーを選びます。
  4. 最後の出力・スキップ・エラーの件数とファイル名を確認します。
  5. 出力画像を開き、形式、寸法、透明部分、背景、色、合成内容を確認します。

JSXの保存と初回実行はスクリプトを実行する方法、繰り返し使う場合の登録はメニューに表示する方法で説明しています。保存したファイル名と、実際に選ぶファイルを一致させます。

Photoshop 2026で実行した結果

2026年10月19日に、Photoshop 2026(27.11.0)とWindows 11 Proで、記事のコードを変えずに CGM_ExportFolderReview.jsx として保存し、[ファイル]→[スクリプト]→[参照]から実行しました。

入力用のフォルダーには、横長、透明な部分がある縦長、拡張子が大文字の正方形、CMYKの4つのPSDを置きました(PSDの用意は別のスクリプトで行ったので、確認には含めていません)。

実行すると、フォルダーを選ぶ画面が2回続けて開きます。

1回目は題名が Select the input PSD folder で入力用のフォルダーを、2回目は Select a separate output folder で出力用のフォルダーを選びます。

スクリプトが開いた出力フォルダーの選択画面。題名はSelect a separate output folderで、out-pngフォルダーを選んでいる
2026-10-19撮影。Adobe Photoshop 2026 (27.11.0)、Windows 11 Pro (10.0.26200)。スクリプトの2回目のフォルダー選択で、出力用のフォルダー(out-png)を選んだところ。左側のフォルダー一覧は塗りつぶしています。

書き出しが終わると、件数とファイルごとの結果が表示されました。

RGBの3つは書き出され、CMYKのPSDは ERROR の行に理由が出て、書き出されませんでした。

スクリプト警告の画面。Output: 3 / Skip: 0 / Error: 1 と、3ファイルのOKとCMYKのPSDのERRORが表示されている
2026-10-19撮影。Adobe Photoshop 2026 (27.11.0)、Windows 11 Pro (10.0.26200)。1回目の実行結果。RGBの3つを書き出し、CMYKのPSDはエラーとして書き出さなかった。

出力された画像は次のとおりです。

入力のPSD初期設定(PNG・縮小なし)JPEG・長辺1000px
横長 1600×900px1600×900pxのPNG1000×563pxのJPEG
縦長 600×1200px(透明な部分あり)600×1200pxのPNG。透明な部分は透明のまま500×1000pxのJPEG。透明だった部分は白
正方形 400×400px(拡張子が大文字の SMALL.PSD)400×400pxの SMALL.png400×400pxの SMALL.jpg(拡大しない)
CMYK 800×800px出力なし(RGB・8bitのみのエラー)出力なし(同じエラー)

JPEGと縮小は、先頭の2行を OUTPUT_FORMAT = "JPEG" と MAX_LONG_EDGE = 1000 に変えた複製を、空の別の出力フォルダーに対して実行した結果です。

結果の表示は、PNGのときと同じく出力3・スキップ0・エラー1でした。

PNGとJPEGのどちらにも、sRGB(sRGB IEC61966-2.1)のICCプロファイルが埋め込まれていました(練習用のPSDはsRGBで作っています)。

拡張子が大文字の SMALL.PSD も対象になり、出力の拡張子は小文字になりました。

処理の後、Photoshopに開いたままの画像は残らず、定規の単位(ピクセル)とダイアログの設定は実行前と同じでした。

同じ出力フォルダーでもう一度実行したとき

同じ入力と出力のフォルダーを選んで2回目を実行すると、書き出し済みの3つはスキップされました。

出力フォルダーのPNGは、更新日時もサイズも1回目のままで、上書きされていませんでした。

CMYKのPSDは出力が無いので、2回目もエラーになりました。

2回目の実行結果の画面。Output: 0 / Skip: 3 / Error: 1 と、3ファイルのSKIPが表示されている
2026-10-19撮影。Adobe Photoshop 2026 (27.11.0)、Windows 11 Pro (10.0.26200)。同じ出力フォルダーでもう一度実行した結果。書き出し済みの画像があるファイルはスキップされた。

書き出し直したいときは、出力フォルダーの古い画像を別の場所へ移してから実行します。

書き出せない・結果が違うとき

症状 確認すること
何も出力されない キャンセル、対象PSDの有無、直下か、既存出力、開いているPSD
RGB/8bitのエラー 元PSDの色モードとビット深度。変換は複製したファイルで行う
PNGの色数や透明度が違う PNG8 = false と透明度の指定、入力の透明部分、実際の出力
JPEGの背景が変わる JPEGは透明度を持たない。入力の背景と出力を照合する
保存時に止まる 書き込み権限、保存名、空き容量、エラーに表示されたPSD
1000pxにならない 上限以下の画像は拡大しない。幅ではなく長辺を制限している

[Web用に保存]は、Adobe公式が案内する書き出し機能です。このJSXはその処理を呼び出すため、現在の画像モードや保存条件に左右されます。Adobe公式:Save for Webも確認してください。

旧コード・動画と今回の確認範囲

旧記事にはJPEG、PNG、縮小JPEGの3例と配置先のコードを掲載していました。原文は末尾の比較資料に残しています。旧説明にあった CGM_PSDtoJPGorPNG.jsx という選択画面を、3つの個別コードが実装しているわけではありません。今回の手順は保存するファイル名を統一し、出力形式は先頭の設定で指定します。

旧PNG例はPNG-8/PNG-24を明示しておらず、旧縮小例は単位の設定を戻していません。フォルダー選択後のキャンセル確認や、既存画像・途中失敗の扱いも不足していました。今回の例との違いを確認してから、旧記事に対応するGitHubのコードを使用してください。

旧記事の動画は過去の操作資料として保持しています。

今回のコードを実行した記録ではありません。

今回のコードは、2026年10月19日にPhotoshop 2026(27.11.0)とWindows 11 Proで実行して確かめました。

旧コードの4ブロックは、2026年の版では実行していません。

旧掲載コードの比較資料

旧コード・コマンド・出力例の原文です。今回の実行結果と区別して参照してください。

旧コード4ブロックを表示(原文・全例の現行版動作は未検証)
app.bringToFront();
main();

function main()
{
    var folderObj = new Object();
    var sourceFolder = Folder.selectDialog('フォルダを選択してください:', Folder(folderObj));
    var docs = sourceFolder.getFiles("*.psd");
    var fileArray = new Array();
    var len = docs.length;

    for (var i = 0; i < len; i++)
    {
        var doc = docs[i];
        fileArray.push(doc);
    }

    for (var i = 0; i < fileArray.length; i++)
    {
        var doc = open(fileArray[i]);
        var docName = doc.name;
        if (docName.indexOf(".") != -1)
        {
            var basename = docName.match(/(.*)\.[^\.]+$/)[1]
        } else
        {
            var basename = docName
        }

        exportJpg(doc, sourceFolder, basename + '.jpg');
        doc.close(SaveOptions.DONOTSAVECHANGES);
    }
}

function exportJpg(doc, folder, name)
{
    var file = new File(folder.fsName + "/" + name);
    var options = new ExportOptionsSaveForWeb();
    options.format = SaveDocumentType.JPEG;
    options.includeProfile = false;
    options.interlaced = false;
    options.optimized = true;
    options.lossy = 0;
    options.quality = 100;
    doc.exportDocument(file, ExportType.SAVEFORWEB, options);
}
app.bringToFront();
main();

function main()
{
    var folderObj = new Object();
    var sourceFolder = Folder.selectDialog('フォルダを選択してください:', Folder(folderObj));
    var docs = sourceFolder.getFiles("*.psd");
    var fileArray = new Array();
    var len = docs.length;

    for (var i = 0; i < len; i++)
    {
        var doc = docs[i];
        fileArray.push(doc);
    }

    for (var i = 0; i < fileArray.length; i++)
    {
        var doc = open(fileArray[i]);
        var docName = doc.name;
        if (docName.indexOf(".") != -1)
        {
            var basename = docName.match(/(.*)\.[^\.]+$/)[1]
        } else
        {
            var basename = docName
        }

        exportPng(doc, sourceFolder, basename + '.png');
        doc.close(SaveOptions.DONOTSAVECHANGES);
    }
}

function exportPng(doc, folder, name)
{
    var file = new File(folder.fsName + "/" + name);
    var options = new ExportOptionsSaveForWeb();
    options.format = SaveDocumentType.PNG;
    options.optimized = true;
    options.interlaced = false;
    doc.exportDocument(file, ExportType.SAVEFORWEB, options);
}
app.bringToFront();
main();

function main() {
    var folderObj = new Object();
    var sourceFolder = Folder.selectDialog('フォルダを選択してください:', Folder(folderObj));
    var docs = sourceFolder.getFiles("*.psd");
    var fileArray = new Array();
    var len = docs.length;

    for (var i = 0; i < len; i++) {
        var doc = docs[i];
        fileArray.push(doc);
    }

    for (var i = 0; i < fileArray.length; i++) {
        var doc = open(fileArray[i]);
        var docName = doc.name;
        if (docName.indexOf(".") != -1) {
            var basename = docName.match(/(.*)\.[^\.]+$/)[1]
        } else {
            var basename = docName
        }
        doc.mergeVisibleLayers(); //表示レイヤーを結合
        preferences.rulerUnits=Units.PIXELS; //単位をピクセルに
 
        //幅1000pxより大きい場合は比率を維持しつつ幅1000pxに
        if(doc.width>1000){
        doc.resizeImage(1000, undefined, undefined, ResampleMethod.AUTOMATIC, 0);
        }
          //高さ1000pxより大きい場合は比率を維持しつつ高さ1000pxに
        if(doc.height>1000){
        doc.resizeImage(undefined, 1000, undefined, ResampleMethod.AUTOMATIC, 0);
        }  
        
        exportJpg(doc, sourceFolder, basename + '.jpg');
        doc.close(SaveOptions.DONOTSAVECHANGES);
    }
}

function exportJpg(doc, folder, name) {
    var file = new File(folder.fsName + "/" + name);
    var options = new ExportOptionsSaveForWeb();
    options.format = SaveDocumentType.JPEG;
    options.includeProfile = false;
    options.interlaced = false;
    options.optimized = true;
    options.lossy = 0;
    options.quality = 100;
    doc.exportDocument(file, ExportType.SAVEFORWEB, options);
}
C:\Program Files\Adobe\Adobe Photoshop CC\Presets\Scripts\
スポンサーリンク

よくある質問:PSDを開いて合成画像を書き出す

この処理では何ができますか?

入力フォルダーのPSDを順に開き、各PSDの合成画像をPNGまたはJPEGとして書き出します。PSDごとに1枚の画像を作る用途で、書き出したあと元のPSDは保存せずに閉じます。

レイヤーごとやレイヤーカンプごとに書き出したいときはどうしますか?

この処理はPSDごとに1枚の画像を作る用途です。レイヤー単位ならレイヤーを個別ファイルに書き出す方法、カンプ単位ならレイヤーカンプの書き出しを使います。

最初に何を決めておけばよいですか?

保存先と形式、縮小の条件を先に決めておくと、出力結果を照合できます。作業用にPSDを複製し、入力用と出力用のフォルダーを分けてください。最初は2〜3ファイルで確認します。

どんなPSDが処理の対象になりますか?

選択したフォルダー直下のPSDが対象で、サブフォルダーは再帰処理しません。すでにPhotoshopで開いているPSDは、ファイルのパスを照合してスキップします。色モードとビット深度はRGB・8bitのみで、自動では変更しません。

同じ名前の画像が出力フォルダーにあるとどうなりますか?

既存の出力を見つけたファイルはスキップします。出力フォルダーはこの処理専用にしてください。書き出し直前にも存在を確認しますが、他のプログラムによる同時書き込みまでは防げません。

画像を縮小することはできますか?

上限を指定したときだけ長辺を縮小し、縦横比を維持します。上限以下の画像は拡大しません。幅ではなく長辺を制限しているので、1000pxの指定でも幅が1000pxにならない場合があります。

何も出力されないときは何を確認しますか?

キャンセルしていないか、対象のPSDがあるか、フォルダー直下に置いているか、すでに出力が存在しないか、対象のPSDを開いたままにしていないかを確認します。RGB/8bitのエラーが出る場合は、元PSDの色モードとビット深度を見て、変換は複製したファイルで行います。

PNGの透明度やJPEGの背景が想定と違うのはなぜですか?

PNGは、PNG-24と透明度の指定、入力の透明部分、実際の出力を確認します。JPEGは透明度を持たないので、入力の背景と出力を照合してください。[Web用に保存]の処理を呼び出しているため、現在の画像モードや保存条件にも左右されます。

出力された数が合っていれば、内容も正しいと言えますか?

いいえ。出力数は、ファイルが存在してサイズが0より大きいことを確認した数で、画像の内容が正しいことを保証するものではありません。出力画像を開き、形式、寸法、透明部分、背景、色、合成内容を確認してください。

このコードはPhotoshopで実機検証されていますか?

はい。

2026年10月19日に、Photoshop 2026(27.11.0)とWindows 11 Proで実行し、PNGとJPEGの書き出し、長辺の縮小、既存の画像があるときのスキップ、CMYKのPSDのエラーを確かめました。

記事の動画は過去の操作資料で、今回のコードの実行記録ではありません。

Mac、ほかの版、16bitのPSDやサブフォルダーのあるフォルダーなどは試していません。

次に学ぶ・作業環境を選ぶ

学習を続けたい方や、作業環境を整えたい方は、目的に合うガイドをご覧ください。

Photoshopのおすすめ書籍

動作要件とPCの確認項目

周辺機器の優先度

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次