Photoshopのスクリプトでレイヤーが選択されているかどうかを検出する
フォトショで「選択されているレイヤー」に対して処理を行いたかったのですが、先に「ドキュメントが開いているか」「レイヤーが選択されているか」をチェックしなきゃいけなくて、そこがなかなか骨が折れたのでメモしておきます。
選択されていない場合は一番上のレイヤーを取得しちゃう
参考にさせていただいたサイトにも書かれていますが、
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行目で下の「すべてのレイヤーとレイヤーセットの数を数える関数」を呼び出しています。
大きな流れは、「現状を数える」→「複製」→「もう一度数える」→「判定」という形です。選択レイヤーがある場合は、複製後レイヤーが増えているはずなので、複製前後の数の違いで判定しています。
コメントは承認制ですので、反映までしばらくお待ち下さい。(稀にスパムの誤判定にて届かないこともあるようですので、必要な際はお問い合わせからお願い致します。)
YouTubeでQ&Aコンテンツを企画しています
運営しているYouTubeチャンネルで、ご相談やご質問を募集しています。動画のコメントやお問い合わせページからお気軽にご相談をお寄せください。