Photoshopで開いている文書を複製し、選んだフォルダーへ「元の名前_export.psd」として保存するJSXの例です。元の文書を保存・統合・閉じず、複製を直接参照して処理します。複数の文書が開いていても、配列の位置から元の文書を推定しません。
この更新ではコードの構文と模擬条件を検査しています。Photoshopでの複製・PSD保存・開き直しは未検証です。まず自作の文書で試し、元ファイルと出力PSDを別に照合してください。
元文書・複製・保存済みファイルの違い
| 対象 | この例の扱い |
|---|---|
| 元文書 | 実行開始時のapp.activeDocumentを保持する。未保存文書も選択フォルダーへ出力できる構成。元文書のsave/closeは呼ばない。 |
| 複製 | duplicate(…, false)の戻り値を使う。レイヤーを保持し、自動で統合しない。 |
| 出力 | 明示した_export.psd。既存同名なら複製前に停止。保存前にも再確認する。 |
| 成功の照合 | ファイルの存在とサイズだけではPSDの内容を証明できない。開き直して寸法・レイヤー・表示・色を確認する。 |
旧コードはdocuments.length−2から保存先の文書を選び、複製にmergeVisibleLayersを適用していました。文書の並びに依存する参照と、レイヤー構造を変える処理は分けます。単なるバックアップが目的ならレイヤーを保持し、統合が必要な場合だけ複製に対して別途処理してください。mergeVisibleLayersは可視レイヤーの統合で、すべてのレイヤーを一律にフラット化する説明とは異なります。
AdobeのJavaScript Scripting Reference 2020のDocument.duplicate、saveAs、closeとPhotoshopSaveOptionsを参照しています。UXPのsaveAs APIとは別です。保存形式ごとの保持項目はAdobeのファイル保存資料でも確認できます。
CGM_DuplicateAndSave.jsxの新しい例
次の全体をUTF-8の.jsxとして保存し、ファイル→スクリプト→参照から1回実行します。旧コードへ追記せず別ファイルにしてください。メニューへ登録する配置先は、スクリプトメニューの記事を参照します。
#target photoshop
(function () {
if (app.documents.length === 0) {
alert("文書を開いてください。");
return;
}
var source = app.activeDocument;
var copy = null;
var output = null;
try {
var folder = Folder.selectDialog("複製PSDの保存先を選択してください");
if (folder === null) { return; }
var base = source.name.replace(/\.[^.]+$/, "");
base = base.replace(/[\\\/:*?"<>|]/g, "_").replace(/[ .]+$/, "");
if (!base) { base = "document"; }
output = new File(folder.fsName + "/" + base + "_export.psd");
if (output.exists) {
alert("同名ファイルがあるため保存しません: " + output.fsName);
return;
}
copy = source.duplicate(base + "_export", false);
var options = new PhotoshopSaveOptions();
options.layers = true;
options.alphaChannels = true;
options.annotations = true;
options.embedColorProfile = true;
options.spotColors = true;
if (output.exists) { throw new Error("保存直前に同名ファイルが見つかりました。"); }
copy.saveAs(output, options, true, Extension.LOWERCASE);
if (!output.exists || output.length === 0) {
throw new Error("保存先ファイルを確認できません。複製を残します。");
}
copy.close(SaveOptions.DONOTSAVECHANGES);
copy = null;
alert("保存処理が戻りました: " + output.fsName + "\nPSDを開き直して内容を確認してください。");
} catch (error) {
alert("中断: " + error.message + "\n複製が残っている場合は内容を確認してください。自動再実行はしません。");
} finally {
try { app.activeDocument = source; } catch (restoreError) {
alert("元の文書へ表示を戻せませんでした: " + restoreError.message);
}
}
}());
名前の禁止文字と末尾の空白・ピリオドを置き換えます。同名の既存ファイルを自動で上書きしたり、連番を推測して保存したりしません。別フォルダーを選ぶか、元文書の複製名を整理してから実行してください。既存確認は排他的なファイルロックではないため、同じ保存先へ別の処理を同時に書き込まないでください。
初回の確認条件と期待値
| 条件 | 確認すること |
|---|---|
| 文書なし/保存先取消 | 文書・ファイルを作成しない。 |
| RGBの自作2レイヤー文書 | 複製PSDを1つ出力し、レイヤーを保持。元文書は開いたまま。 |
| 複数文書・未保存文書 | 実行時に前面の文書の内容を保存。別タブのパスや名前を使わない。 |
| 同名PSDあり | 上書きせず停止。既存ファイルのハッシュを実行前後で比較。 |
| 保存失敗 | 複製は確認用に残す。書きかけの出力がある場合は開き直して検査し、自動削除や再実行をしない。 |
以上は期待値で、今回のPhotoshop実行結果ではありません。保存後はPSDを開き直し、寸法・レイヤー数/名前・可視状態・画像・プロファイルを比較します。原本ファイルのハッシュ、元文書の未保存状態とほかの文書が変わっていないことも確認してください。PSBや特殊なモード・大きな文書は、このPSD例で保存できると一律に扱いません。
旧コードと配布元
旧コードの参照資料(実行しない)
旧コードは文書配列から元文書を推定し、可視レイヤー統合と固定名保存を行います。同名上書き・保存失敗・文書なし・未保存の条件を扱っていません。比較用に原文を保持しますが、新例と混ぜて実行しないでください。
旧コード 1
(function(){
//ドキュメントを複製
var copiedDoc = app.activeDocument.duplicate();
//処理(レイヤーを統合)
mergeLayers();
//名前をつけて保存
saveSceneAs();
// 複製したドキュメントを保存せず閉じる
activeDocument.close(SaveOptions.DONOTSAVECHANGES);
//アラート
alert('終わったよ♪');
//レイヤーを統合
function mergeLayers() {
docObj = activeDocument;
docObj.mergeVisibleLayers();
}
function saveSceneAs() {
//ドキュメント数を調べて、オリジナルのドキュメントナンバーを取得
n = documents.length -2;
//オリジナルのドキュメントのパスと名前を取得
var filePath = documents[n].path;
var fileName = documents[n].name.replace(/\.[^\.]+$/, '');
//プリフィックスを追加
var fileFullName = filePath + "/" + fileName + "_export";
//保存オプション
var psdObj = new File(fileFullName);
var psdOpt = new PhotoshopSaveOptions();
psdOpt.alphaChannels = true;
psdOpt.annotations = true;
psdOpt.embedColorProfile = false;
psdOpt.layers = true;
psdOpt.spotColors = false;
//名前をつけて保存
activeDocument.saveAs(psdObj, psdOpt, true, Extension.LOWERCASE);
}
})() ;旧コード 2
C:\Program Files\Adobe\Adobe Photoshop CC\Presets\Scripts\旧GitHub配布は更新していません。
JSXの文書/レイヤー/ファイル操作、レイヤーごとの書き出しとは目的が異なります。文書全体を別名で残す場合にこの例を使います。





