画像のプロファイルをsRGBへ変換し、別フォルダーにJPEGのコピーを保存するスクリプトです。
元ファイルは保存せずに閉じ、入力ファイル名の拡張子も出力名に残します。
sample.pngとsample.jpgは、sample.png.jpgとsample.jpg.jpgになるため、同じベース名の画像を区別できます。
標準機能とJSXの使い分け
フォルダーの画像をsRGBのJPEGにするだけなら、標準のイメージプロセッサーでも対応できます。[JPEGとして保存]と[プロファイルをsRGBに変換]を選び、[ICCプロファイルを含める]も確認してください。
このJSXは、入力の拡張子を残した命名、既存出力があるときの中断、失敗したファイルの一覧が必要な場合の例です。初めて外部JSXを使う場合は、スクリプトを参照して実行する手順も確認してください。
練習用データと実行前の条件
JSXと練習用画像のZIPをダウンロードし、任意の作業フォルダーへ展開します。
画像は架空の256×128pxデータで、Photoshopの実画面や実機での書き出し結果ではありません。
sample.pngとsample.jpgだけを入力フォルダーへコピーし、出力用の空フォルダーを別に作ります。
入力はプロファイル付きのRGB・8bit画像を使います。
実行前に[編集]→[カラー設定]のRGBポリシーを確認します。元の埋め込みプロファイルから変換する場合は[埋め込まれたプロファイルを保持]を選びます。[作業用スペースに変換]では画像を開く段階で色が変換され、[オフ]では埋め込みプロファイルが無視されます。変更前の設定を控え、必要なら実行後に戻してください。
コードが判定するのは、開いた後の文書のプロファイルです。元ファイルにICCプロファイルが入っていたかどうかを、別途検査するコードではありません。プロファイルなしの画像はこの例の入力に含めず、読み込み時の警告で元の色空間を推測して割り当てないでください。
CMYK、16bit、プロファイルなしの文書はスクリプト内で除外します。
プロファイルが不明な画像へsRGBを割り当てると色の解釈が変わるため、コピーの正しい元プロファイルを先に確認してください。
JPEGでは透明を保持できないため、透明が必要な画像にはこの処理を使いません。
既存の文書は自分で保存して閉じてください。
スクリプトは文書が開いている場合に停止するため、作業中の文書を勝手に閉じません。
入力と出力に同じフォルダーは選べず、出力先に予定の名前が1件でも存在すると、画像を開く前に全体を停止します。
コピーして使うJSXコード
#target photoshop
(function () {
if (app.documents.length > 0) {
alert("Save and close your open documents before running this script.");
return;
}
var src = Folder.selectDialog("Select the input folder");
if (!src) return;
var dst = Folder.selectDialog("Select a separate, empty output folder");
if (!dst) return;
if (src.fsName.toLowerCase() === dst.fsName.toLowerCase()) {
alert("Input and output folders must be different.");
return;
}
var files = src.getFiles(function (f) {
return f instanceof File && /\.(psd|tif|tiff|jpg|jpeg|png)$/i.test(f.name);
});
var targets = [], seen = {}, i;
if (!files.length) { alert("No supported input files."); return; }
for (i = 0; i < files.length; i++) {
// Keep the original extension: sample.png.jpg and sample.psd.jpg.
var target = new File(dst.fsName + "/" + decodeURI(files[i].name) + ".jpg");
var key = target.fsName.toLowerCase();
if (target.exists || seen[key]) {
alert("Output already exists or is duplicated: " + target.fsName);
return;
}
seen[key] = true;
targets.push(target);
}
var opts = new JPEGSaveOptions();
opts.quality = 10;
opts.embedColorProfile = true;
var saved = 0, failed = [], closeErrors = [];
for (i = 0; i < files.length; i++) {
var doc = null;
try {
if (targets[i].exists) throw new Error("Output appeared after the initial check.");
doc = app.open(files[i]);
if (doc.mode !== DocumentMode.RGB || doc.bitsPerChannel !== BitsPerChannelType.EIGHT) {
throw new Error("Use an 8-bit RGB input copy.");
}
if (doc.colorProfileType === ColorProfile.NONE) {
throw new Error("Assign the correct source profile to a copy first.");
}
doc.convertProfile("sRGB IEC61966-2.1", Intent.RELATIVECOLORIMETRIC, true, false);
if (targets[i].exists) throw new Error("Output appeared before saving.");
doc.saveAs(targets[i], opts, true, Extension.LOWERCASE);
saved++;
} catch (e) {
failed.push(files[i].name + ": " + e.message);
} finally {
if (doc) {
try { doc.close(SaveOptions.DONOTSAVECHANGES); }
catch (e2) { closeErrors.push(files[i].name + ": " + e2.message); }
}
}
// Stop if a document could not be closed; do not accumulate more open files.
if (closeErrors.length) break;
}
alert("Saved: " + saved + " / " + files.length +
"\nFailed: " + failed.length + "\n" + failed.join("\n") +
"\nClose errors: " + closeErrors.length + "\n" + closeErrors.join("\n"));
}());
実行と結果の確認
コードをUTF-8のarticle-1388.jsxとして保存し、Photoshopの[ファイル]→[スクリプト]→[参照]で選びます。
ZIP内の同名ファイルを使う場合は再保存不要です。
最初のダイアログで入力フォルダー、次のダイアログで空の出力フォルダーを選びます。
途中でキャンセルした場合は画像を開きません。
練習用の2画像では、完了表示のSavedが2、Failedが0、Close errorsが0になることを確認します。
配布した2画像には、生成時からsRGBのICCプロファイルを埋め込んでいます。この入力で確かめるのは保存・命名・プロファイルの保持です。Adobe RGBなどからsRGBへの変換を確かめる場合は、元のプロファイルが分かっている別のRGB・8bitコピーを用意してください。
出力JPEGを開き直し、256×128pxであることと、文書のプロファイルがsRGB IEC61966-2.1になっていることを確認してください。
原本の更新日時と内容が変わっていないことも確認します。
見た目だけでプロファイル変換の成功を判断しないでください。
qualityの10はJPEGSaveOptionsの0〜12の設定です。
[書き出し形式]の画質パーセントとは別の値なので、その画面の数値をコードへそのまま移しません。
embedColorProfile=trueで出力プロファイルを埋め込みます。
途中で失敗した場合と戻し方
| 表示・条件 | 次に行う確認 |
|---|---|
| Output already exists | 別の空フォルダーを選ぶ。既存画像を自動上書きしない |
| Use an 8-bit RGB input copy | 原本を残して複製をRGB・8bitに準備する |
| Assign the correct source profile | 元の色空間を確認する。不明な画像に推測で割り当てない |
| Failedが1以上 | 該当ファイルとメッセージを読み、出力を開いて確認する |
| Close errorsが1以上 | 後続処理は停止。残った文書の保存状態を確認する |
各画像はfinallyで保存せずに閉じる処理を試みます。
閉じる処理自体が失敗した場合は、それ以上の画像を開かず停止します。
書き込み失敗後の出力が正常とは限らないため、Savedの数と実ファイルを照合してください。
元の状態へ戻す場合は原本を開き、不要な出力は別フォルダーへ退避します。
同じ出力先を他のアプリや別のバッチと同時に使わないでください。
保存直前にも存在確認を行いますが、確認と保存を一つの排他処理にする仕組みではありません。
シンボリックリンクなどで同じ場所を別パスとして選ぶ運用も避けます。
確認範囲と公式資料
2026年10月3日、Adobeのスクリプト実行手順、カラーマネジメントポリシー、イメージプロセッサーの設定を確認しました。
この記事の配布コードと本文の一致、練習用画像の寸法・RGBモード・ICCプロファイルを確認しました。Node.jsの模擬APIでは、中断、既存出力、RGB・8bitの条件、変換・保存・終了時のエラーなど16項目を確認しています。
Photoshop本体でのDOM操作、色変換、JPEG出力は未検証のため、まず練習用コピーで確認してください。
