PhotoshopJSXでレイヤーが選択されているかどうかを検出する

PhotoshopJSXでレイヤーが選択されているかどうかを検出する

フォトショで「選択されているレイヤー」に対して処理を行いたかったのですが、先に「ドキュメントが開いているか」「レイヤーが選択されているか」をチェックしなきゃいけなくて、そこがなかなか骨が折れたのでメモしておきます。


選択されていない場合は一番上のレイヤーを取得しちゃう

参考にさせていただいたサイトにも書かれていますが、

var ly = activeDocument.activeLayer;

と書いただけだと、選択されていなくても一番上(最前面)のレイヤーが返ってきてしまうのですよね。そうではない…、そうではないんだ……ッ!! で、いろいろ試行錯誤したのですが、別の処理で「ドキュメント内のすべてのレイヤー・レイヤーセットの総数を数える」関数を利用する場面があったので、これを使ってなんとかならないかな、と思って作った結果です。

これがベストというわけじゃない気がするので、参考程度に御覧ください。

参考

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

コード

メイン

try {
	if ( documents.length == 0 ) { //開いているドキュメントがゼロなら
		throw new Error( "ドキュメントが開いていません" );
	}
	var doc = activeDocument; //ドキュメントを取得
	if ( !isSelected( doc ) ) { //選択レイヤーが存在しなければ
		throw new Error( "レイヤーが選択されていません" );
	}
	
	//選択レイヤーがあるので処理をします!
	
} catch ( e ) { //例外
	alert( e.message ); //例外メッセージ出力
}

まずこちらがメインコード。6行目でドキュメントを引数にして、選択レイヤーの存在有無をTrue/Falseで返す自作関数です。ドキュメントが開いていない、レイヤーが選択されていない場合12行目にジャンプしてメッセージ出力して処理をせずに終了、という流れです。

選択レイヤーの存在有無を返す関数

//選択レイヤーが存在するか確認する関数
function isSelected( doc ) {
	//すべてのレイヤーとレイヤーセットの数を数える
	allLsLen = -1; //初期化
	allLyLen = 0;
	getAllLyLen( doc ); //数える
	var beforeLsLen = allLsLen;
	var beforeLyLen = allLyLen;
	
	//存在確認としての複製
		var desc0 = new ActionDescriptor();
			var ref0_1 = new ActionReference();
			ref0_1.putEnumerated( charIDToTypeID( "Lyr " ), charIDToTypeID( "Ordn" ), charIDToTypeID( "Trgt" ) );
		desc0.putReference( charIDToTypeID( "null" ), ref0_1 );
		desc0.putString( charIDToTypeID( "Nm  " ), "tmp" );
		desc0.putInteger( charIDToTypeID( "Vrsn" ), 5 );
			var list0_2 = new ActionList();
			list0_2.putInteger( 179 );
		desc0.putList( charIDToTypeID( "Idnt" ), list0_2 );
	executeAction( charIDToTypeID( "Dplc" ), desc0, DialogModes.NO );
	
	//再度すべてのレイヤーとレイヤーセットの数を数える
	allLsLen = -1; //初期化
	allLyLen = 0;
	getAllLyLen( doc ); //数える
	var afterLsLen = allLsLen;
	var afterLyLen = allLyLen;
	
	//判定
	if ( beforeLsLen == afterLsLen && beforeLyLen == afterLyLen ){ //数が同じなら
		return false; //存在しない
	}else{
		executeAction( charIDToTypeID('undo'), undefined, DialogModes.NO ); //複製をアンドゥ
		return true; //存在する
	}
}

//すべてのレイヤーとレイヤーセットの数を数える関数
function getAllLyLen(layObj){
	var n = layObj.artLayers.length;
	for ( var i = 0; i < n; i++ ) {
		allLyLen++;
	}
	var ns = layObj.layerSets.length;
	allLsLen++;
	for ( var i = 0; i < ns; i++ ) {
		getAllLyLen(layObj.layerSets[i]); //再帰処理
	}
}

2つの関数に分かれていて、6行目と25行目で下の「すべてのレイヤーとレイヤーセットの数を数える関数」を呼び出しています。

大きな流れは、「現状を数える」→「複製」→「もう一度数える」→「判定」という形です。選択レイヤーがある場合は、複製後レイヤーが増えているはずなので、複製前後の数の違いで判定しています。

公開日:2019/09/27

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください

コメントは承認制ですので、反映までしばらくお待ち下さい。(稀にスパムの誤判定にて届かないこともあるようですので、必要な際はお問い合わせからお願い致します。)