LoginSignup
2
0

More than 3 years have passed since last update.

Photoshop document.duplicate()で意図しないドキュメントが複製される

Posted at

ちょっとハマったのでメモ。
ちなみに検証しているPhotoshopのバージョンはCC2019(v20.0.6)です。

Photoshopスクリプトでのdocument.duplicate()

document.duplicate()は名前の通り、複製のためのメソッドです。

Photoshop CC JavaScript Referenceでの記述は以下の通り

Creates a duplicate of the document object.
The optional parameter name provides the name for the duplicated document.
The optional parameter mergeLayerOnly indicates whether to only duplicate merged layers.

google先生の翻訳

ドキュメントオブジェクトの複製を作成します。
オプションのパラメータ名は、複製されたドキュメントの名前を提供します。
オプションのパラメーターmergeLayerOnlyは、マージされたレイヤーのみを複製するかどうかを示します。

普通にドキュメント複製される、ということですね。
使い方は以下の通り。

duplicate_sample.jsx
// 現在のアクティブドキュメントを取得
var document = app.activeDocument;

// documentが「copy.psd」として複製される
var copy_doc = document.duplicate("copy.psd");

ちなみにこのサンプルは正常に動きます。

意図しないduplicate()の挙動

遭遇したduplicateの挙動はactiveDocumentではないドキュメントを複製(duplicate)しようとすると、activeDocumentが複製されるというもの。

具体的な流れは以下の通り

  1. A.psdを開く
  2. A.psdにリンクされているB.psdを開く(この時点で一度activeDocumentはB.psdに移る)
  3. B.psdはそのまま、一度明示的にA.psdにactiveDocumentを移す
  4. B.psdを複製しようとする
  5. A.psdが複製される

なんでこんな面倒なことしているんだ、という話は長くなるので割愛します。
具体的なコードの例は以下の通り。

var document = app.activeDocument;
var root_layers = document.layers;

var link_docs = [];

for(var i=0;i<root_layers.length;i++)
{
  var layer = root_layers[i];

  // SmartObjectかチェックする
  if(layer.kind!= LayerKind.SMARTOBJECT) continue;

  // SmartObjectを開く
  app.activeDocument.activeLayer = layer;
  var idplacedLayerEditContents = stringIDToTypeID( "placedLayerEditContents" );
  var desc3 = new ActionDescriptor();
  executeAction( idplacedLayerEditContents, desc3, DialogModes.NO );

  // 現在のactiveDocumentを取得
  var link_doc = app.activeDocument;

  // リンクしてあるpsdかチェック
  var document_path = link_doc.fullName.toString();
  if(document_path != undefined 
    && document_path.indexOf(Folder.temp) == -1)
  {
    // リンクされているドキュメントを一時的に保存しておく
    link_docs.push(link_doc);
  }
}

// 諸々な都合のため一度元のdocumentにactiveDocumentを戻す
app.activeDocument = document;

for(var i=0;i<link_docs.length;i++)
{
  var link_doc = link_docs[i];
  alert(link_doc.name); // この時点では正しい「リンクされているドキュメント名がアラートで表示される」
  link_doc.duplicate(); // document(元の親psd)が複製されてしまう
}

解決策は、複製したいドキュメントをちゃんとactiveDocumentにするということです

for(var i=0;i<link_docs.length;i++)
{
  var link_doc = link_docs[i];

  // ここでちゃんとactiveDocumentにする ---------------------------
  app.activeDocument = link_doc;
  // --------------------------------------------------------

  alert(link_doc.name); // この時点では正しい「リンクされているドキュメント名がアラートで表示される」
  link_doc.duplicate(); // リンクしてあるドキュメントがちゃんと複製される
}

そんなに複雑なことをしていなければなかなか遭遇しなさそうな挙動ですが、パッと発生すると何が起こったか一瞬わからないので、要注意!
私が知らないだけでこれが正しい挙動という記述がどこかにあるのかもしれないですが、私個人としてはバグのように認識しているので、どこかのバージョンアップで修正されると嬉しいです。

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0