Skip to main content
Participant
August 29, 2021
Answered

Illustratorのscriptでembed()で生成されるRasterItemを取得したい

  • August 29, 2021
  • 2 replies
  • 1457 views

placedItem.embed();

した後、placedItemが削除され、代わりにRasterItemが生成されます。

このRasterItemがどれであるか確実に取得、判別するのが目的となります。

 

テスト環境は

・Illustrator Ver25.4.1

・Windows10pro 21H1

・javascript(jsx)

・リンク画像の形式はeps

「リンクされたEPSに低解像と表示用画像を使用」をon

となっています。

 

現状、行いたい作業は選択されたリンク画像(placeditem)を埋め込み(.embed())をして、それにラスタライズ(.rasterize())を行うことで、疑似的なリンク画像のリサイズにしようと考えています。

 

ですので、埋め込んだ後に生成されるRasterItemを見つける必要があるのですが、存在すると思っていた.embed()の返り値はリファレンスによると「Nothing」とあり、実際に出力は「undefined」となります。

 

「.absoluteZOrderPosition」は一つだけなら問題ないのですが、複数選択の際に一つ目しか同一になりませんでした。
widthやleftなどの情報から判別しようと考えましたが、.embed()後には小数点1位以下で微妙に値が変わるようです。そこで誤差を織り込んだ判定を行うと一応稼働するものはできました。
 
ですが顧客に仕様を説明すると、不安定な方法は望ましくないと言われ行き詰っています。「.absoluteZOrderPosition」値の変動の法則を解析することもおそらく望まれてはいないと思われます。
 
ご助力いただければ幸いです。
 
また機能改善リクエストとして、.embed()で生成されるRasterItemをリターンしたいただけると助かります。
 
 
This topic has been closed for replies.
Correct answer asanagiak47

返信ありがとうございます。

 

結論から言いますと、解決しました。

私はリンク画像(placeditem)を埋め込み(.embed())をするとRasterItemになると思い込んでいたのですが、

正解は

リンク画像の形式がepsの場合はGroupItemになる

リンク画像の形式がeps以外の場合はRasterItemになる

でした。

GroupItemの方はその中に、クリッピンググループがあり、その中にクリッピングパスとRasterItemがあります。このRasterItemにnameはないので見つからなかったわけです。

 

これをもとに見本コードを作ると

var keyword = "target";

var selectItems = app.activeDocument.selection;

for(var i = 0; i < selectItems.length; i++) {
  selectItems[i].name = keyword;
  selectItems[i].embed();
}

var gi = app.activeDocument.groupItems;
for(var i = 0; i < gi.length; i++) {
  if( gi[i].name == keyword ){
    //ここで埋め込まれたアイテムの処理
  }
}
var ri = app.activeDocument.rasterItems;
for(var i = 0; i < ri.length; i++) {
  if( ri[i].name == keyword ){
    //ここで埋め込まれたアイテムの処理
  }
}
alert("完了");

になると思います。

 

返信いただいたおふた方には、私の先入観で説明が足りずご迷惑をおかけしました。

ありがとうございました。

 

2 replies

onthehead
Participating Frequently
August 30, 2021

まず、リンク画像群を埋め込む前に、画像に適当な名称を割り当てる。
次に、ドキュメント内の埋め込み画像群の中から、先程適当に割り当てた名称の画像だけをピックアップしてラスタライズする。
という方法はどうでしょうか。
オブジェクト名が変更されるのが気持ち悪い場合は、あらかじめオブジェクト名を記憶しておいてラスタライズと同時に元に戻すと良いと思います。

var doc = app.activeDocument;
var sels = doc.selection;
var originNames = [];
var tempName = "karinonamae"; //仮の名称
for (var i = 0; i < sels.length; i++){
	var sel = sels[i];
	if (sel.typename === "PlacedItem"){ //リンク画像なら
		var originName = sel.name;
		originNames.push(originName); //元のオブジェクト名を保存
		sel.name = tempName; //仮の名称に変更
		sel.embed();
	}
}
var rasters = doc.rasterItems;
for (var i = 0; i < rasters.length; i++){
	var raster = rasters[i];
	if (raster.name === tempName){ //仮の名称の画像だったら
		//ここら辺でラスタライズを実行
		raster.name = originNames[i]; //仮の名称を元に戻す
		raster.selected = true;
	}
}
asanagiak47AuthorCorrect answer
Participant
August 30, 2021

返信ありがとうございます。

 

結論から言いますと、解決しました。

私はリンク画像(placeditem)を埋め込み(.embed())をするとRasterItemになると思い込んでいたのですが、

正解は

リンク画像の形式がepsの場合はGroupItemになる

リンク画像の形式がeps以外の場合はRasterItemになる

でした。

GroupItemの方はその中に、クリッピンググループがあり、その中にクリッピングパスとRasterItemがあります。このRasterItemにnameはないので見つからなかったわけです。

 

これをもとに見本コードを作ると

var keyword = "target";

var selectItems = app.activeDocument.selection;

for(var i = 0; i < selectItems.length; i++) {
  selectItems[i].name = keyword;
  selectItems[i].embed();
}

var gi = app.activeDocument.groupItems;
for(var i = 0; i < gi.length; i++) {
  if( gi[i].name == keyword ){
    //ここで埋め込まれたアイテムの処理
  }
}
var ri = app.activeDocument.rasterItems;
for(var i = 0; i < ri.length; i++) {
  if( ri[i].name == keyword ){
    //ここで埋め込まれたアイテムの処理
  }
}
alert("完了");

になると思います。

 

返信いただいたおふた方には、私の先入観で説明が足りずご迷惑をおかけしました。

ありがとうございました。

 

Ten A
Community Expert
Community Expert
August 30, 2021

手っ取り早いのは処理したものにnameプロパティ設定してしまうとかですかね…

 

 

var tg = app.activeDocument.rasterItems;
var rasterOpts = new RasterizeOptions;
rasterOpts.resolution = 150;
for (var i=0;i<tg.length;i++)
{
app.activeDocument.rasterItems[i].selected = true;
app.activeDocument.rasterize(
app.activeDocument.rasterItems[i],
app.activeDocument.rasterItems[i].visibleBounds, rasterOpts);
app.activeDocument.rasterItems[i].selected = true;
app.activeDocument.rasterItems[i].name = "item" + i;
}

 

コード構成をチェックしないと細かいところは指摘できませんが、このような感じで対象をマークしておけは後から確認も可能です。

 

ついでに書いておくと、ここはユーザーコミュニティなので要望を書いても届きません。そのようなフィードバックはUservoiceを利用可能です。
https://illustrator.uservoice.com

Participant
August 30, 2021

返信ありがとうございます。

文章が冗長ですみませんが、ポイントは「.embed()後に生成されるRasterItemにのみ処理をしたい」
の方で、ラスタライズは説明に不要でした。
説明を簡略化するため、「.embed()で生成されたRasterItemにのみ"embedded"と言うnameを付ける」
に置き換えると、やりたいコードは以下のようになります。

var selectItems = app.activeDocument.selection;
var selectItems2 = selectItems;//embedすると配列から消えるのでコピーする

var embeddedItems=[];
for(var i = 0; i < selectItems2.length; i++) {
  embeddedItems.push( selectItems2[i].embed() );//←これが不可能、返り値がない、生成されるrasterItemを取得したい
}

for (var i=0; i<embeddedItems.length; i++){
  embeddedItems[i].name = "embedded";
}

alert("完了");

上記はembeddedItems.push()になにも入らないため動きません。
今考えている一番有望な処理は埋め込まれたRasterItemだけは
RasterItem.file
がエラーになるため、これをtrycatchで捉えて処理をするで、考えています。

var selectItems = app.activeDocument.selection;
var selectItems2 = selectItems;//embedすると配列から消えるのでコピーする

var embeddedItems=[];
for(var i = 0; i < selectItems2.length; i++) {
  selectItems2[i].embed();
}

var ri = app.activeDocument.rasterItems;
for(var i = 0; i < ri.length; i++) {
  try {
    $.writeln(ri[i].file);
  } catch (error) {
    ri[i].name = "embedded";
  }
}

alert("完了");

これも却下される可能性がありそうです。

 

要望の件、ありがとうございます。参考にさせていただきます。