PhotoshopおよびExtendScript Toolkitを使用した画像の処理

多くの場合、写真の束で何かをする必要があります。 これを実現するには、いくつかの方法があります。 後者の方法の長所と短所は、カットの下で考慮されます。 おまけとして、文書化されていないPhotoshop APIを見てみましょう。



必要になります

理論



Photoshopには、Photoshopの多くの機能をカバーするCOM APIがあります。 もちろん、JSまたはVBSスクリプトから使用できます。 Adobeは、オートコンプリートとブレークポイントを備えたIDEを開発者に親切に提供しました。 サポートされている言語は、JScript、VBScript(Win)、およびAppleScript(Mac)です。 ほとんどの人がJScriptを最もよく理解しているので、私はJScriptに決めました。



IDE



彼女の名前はExtendScript Toolkitです。 ここにあります: ExtendScriptツールキット

彼女に私を襲ったのは: スクリプトはjsx形式で保存できます。スクリプトを開くと、「スクリプトを実行または編集しますか?」という質問が表示されます。

jsxをコンパイルして([ファイル]→[バイナリとしてエクスポート])、jsxbin拡張子を持つファイルが作成されると便利です。 その内容は次のようになります。

@JSXBIN@ES@2.0@MyBbyBnAIMVbyBn0AHJWn



特に、注文のためにPhotoshopのスクリプトを記述する必要があり、ソースを提供したくない場合に便利です。 私はそれを逆コンパイルする可能性について詳細に理解していませんでしたが、変数を変更し、まだいくつかの最適化を行っていると思います。

そのため、IDEは一見不快ですが、約30分間作業した後、慣れます。



スクリプト言語



フレーズで始まる

#target photoshop



これは、Adobeライブラリを使用した通常のJavaScriptです。

ファイルシステムを操作するツール、ソケットのサポート、リフレクション、XMLがあります。 クラスObjectは。

Photoshopに接続するには、グローバルアプリオブジェクトがあり、ActiveXObjectを実行する必要はありません。 その中のアクティブドキュメントはapp.activeDocumetです。 警告機能は、Photoshopでメッセージを表示します。

エラーがクラッシュしても何も起こらず、スクリプトは何もなかったかのように実行を静かに停止します。

測定値(px、pt、cm、mm)を相互に変換する方法が気に入りました。

app.activeDocument.width. as ( "px" );



なぜなら ExtendScriptはクロスプラットフォームであり、ファイルパスは/ d / Temp / ...



生きている例



タスク:フォルダーには100個のファイルがあります。 PSDファイルにあるロゴをそれぞれに埋め込む必要があります。

ロゴの例:

ロゴの例

スクリプトは次のとおりです。

#target photoshop

app.bringToFront(); // Photoshop. , , .

var Constants = { /* - */ }

ProcessDir(Constants.InputDir, Constants.OutputDir);

function ProcessDir(dir, outDir) {

var folder = Folder(dir); // Adobe-

var files = folder.getFiles(Constants.FileMask); // , (*.jpg,*.png) .

var outFolder = Folder(outDir);

if (!outFolder.exists) {

if (!outFolder.create()) {

alert( "Cannot create output folder" );

return ; //

}

}

var totalFiles = 0;

for ( var fileNum in files) {

var outFile = GetOutputFileName(files[fileNum], outFolder.fullName); //

AddLogoToFile(files[fileNum], outFile); // ,

totalFiles++;

}

alert(totalFiles + " files processed" ); // Photoshop-

}

function AddLogoToFile(file, outputFile) {

var photoFile = File(file); // , open

var logoFile = File(Constants.AddLogo.LogoPath);



app.open(logoFile); //

app.activeDocument.artLayers[ "Text" ].copy(); // ArtLayers – . "Text"

var logoWidth = app.activeDocument.width. as ( "px" );

var logoHeight = app.activeDocument.height. as ( "px" );

app.activeDocument.close();



app.open(photoFile); //



var width = app.activeDocument.width. as ( "px" );

var height = app.activeDocument.height. as ( "px" );



var logoLayer = app.activeDocument.artLayers.add(); // ,

logoLayer.name = "Logo" ; //



app.activeDocument.paste(); // clipboard



var shape = [ // Photoshop ; ,

[(width - logoWidth) / 2, (height - logoHeight) / 2],

[(width - logoWidth) / 2, (height + logoHeight) / 2],

[(width + logoWidth) / 2, (height + logoHeight) / 2],

[(width + logoWidth) / 2, (height - logoHeight) / 2]

];

app.activeDocument.selection.select(shape);



app.activeDocument.selection.translate( // selection

new UnitValue((width - logoWidth)/ 2, "px" ),

new UnitValue((height - logoHeight) / 2, "px" ));



var minImageDimension = Math.min(width, height); // , 5

var logoScaleMultiplier = minImageDimension / 5 / logoWidth * 100;

app.activeDocument.selection.resize(logoScaleMultiplier, logoScaleMultiplier, AnchorPosition.BOTTOMRIGHT); //



app.activeDocument.selection.deselect();



app.activeDocument.artLayers[ "Logo" ].opacity = 75; //

app.activeDocument.artLayers[ "Logo" ].blendMode = BlendMode.LUMINOSITY; // ,

// blending options! .

SaveFile(outputFile); //

}



function SaveFile(outputFile) {

var isPng = /png$/i.test(outputFile);

var saveOptions;

if (isPng) {

saveOptions = new PNGSaveOptions();

} else {

saveOptions = new JPEGSaveOptions(); /* */

}

app.activeDocument.saveAs(File(outputFile), saveOptions, true , Extension.LOWERCASE)

app.activeDocument.close(SaveOptions.DONOTSAVECHANGES); //

}




スクリプトの準備ができました。 ロゴをPSD形式で作成することはそのままです。たとえば、ロゴを配置するテキストレイヤーが内部にあります。

何が起こるかの例:

ロゴ写真

スクリプトはpastebinに完全にレイアウトされています。



ああ悲しい



Photoshopで最もおいしいのは、ブレンドオプションです! そして、APIには何もありません。 copyLayerStyleがありますが、GUIからも正しく機能しません(ドロップシャドウオプションで遊んで確認できます)。 したがって、もちろん、ロゴを挿入できますが、結果は同じImageMagickを大きく超えることはありません。

UPD:スクリプトからスタイルをすばやく簡単に適用するには、2つの方法があります。

文書化されていないAPIについて少し



ドックを読んだ後(%ProgramFiles%Adobe \ Adob​​e Photoshop CS5 \ Scripting \ Documents \にあります)、Photoshopがユーザーアクションを記録できることがわかります。 これを行うには:
  1. %ProgramFiles%Adobe \ Adob​​e Photoshop CS5 \ Scripting \ Utilities \ to%ProgramFiles%Adobe \ Adob​​e Photoshop CS5 \ Plug-ins \ Automate \から「ScriptListener.8li」ファイルをコピーします。
  2. (再)Photoshopを実行する
  3. 知りたいことをする
  4. デスクトップでScriptListener.jsxとScriptListener.vbsを見つけます
  5. ScriptListener.8liを削除することを忘れないでください(Photoshopの速度が低下します)
待っていたコードを取得したいので、デスクトップからScriptListener.jsxを開きます。 そして、ここで驚きが待っています:ここのファイルには、使用できないゴミがあります:

var idsetd = charIDToTypeID( "setd" );

var desc15 = new ActionDescriptor();

var idnull = charIDToTypeID( "null" );

var ref6 = new ActionReference();

var idPrpr = charIDToTypeID( "Prpr" );

var idLefx = charIDToTypeID( "Lefx" );

ref6.putProperty( idPrpr, idLefx );

var idLyr = charIDToTypeID( "Lyr " );

var idOrdn = charIDToTypeID( "Ordn" );

var idTrgt = charIDToTypeID( "Trgt" );

ref6.putEnumerated( idLyr, idOrdn, idTrgt );

desc15.putReference( idnull, ref6 );

var idT = charIDToTypeID( "T " );

var desc16 = new ActionDescriptor();

var idScl = charIDToTypeID( "Scl " );

var idPrc = charIDToTypeID( "#Prc" );

desc16.putUnitDouble( idScl, idPrc, 100.000000 );

var idDrSh = charIDToTypeID( "DrSh" );

var desc17 = new ActionDescriptor();

var idenab = charIDToTypeID( "enab" );

desc17.putBoolean( idenab, true );

var idMd = charIDToTypeID( "Md " );

var idBlnM = charIDToTypeID( "BlnM" );

var idMltp = charIDToTypeID( "Mltp" );

desc17.putEnumerated( idMd, idBlnM, idMltp );

var idClr = charIDToTypeID( "Clr " );

var desc18 = new ActionDescriptor();

var idRd = charIDToTypeID( "Rd " );

desc18.putDouble( idRd, 0.000000 );

var idGrn = charIDToTypeID( "Grn " );

desc18.putDouble( idGrn, 0.000000 );

var idBl = charIDToTypeID( "Bl " );

desc18.putDouble( idBl, 0.000000 );

var idRGBC = charIDToTypeID( "RGBC" );

desc17.putObject( idClr, idRGBC, desc18 );

var idOpct = charIDToTypeID( "Opct" );

var idPrc = charIDToTypeID( "#Prc" );

desc17.putUnitDouble( idOpct, idPrc, 75.000000 );

var iduglg = charIDToTypeID( "uglg" );

desc17.putBoolean( iduglg, true );

var idlagl = charIDToTypeID( "lagl" );

var idAng = charIDToTypeID( "#Ang" );

desc17.putUnitDouble( idlagl, idAng, 120.000000 );

var idDstn = charIDToTypeID( "Dstn" );

var idPxl = charIDToTypeID( "#Pxl" );

desc17.putUnitDouble( idDstn, idPxl, 5.000000 );

var idCkmt = charIDToTypeID( "Ckmt" );

var idPxl = charIDToTypeID( "#Pxl" );

desc17.putUnitDouble( idCkmt, idPxl, 0.000000 );

var idblur = charIDToTypeID( "blur" );

var idPxl = charIDToTypeID( "#Pxl" );

desc17.putUnitDouble( idblur, idPxl, 5.000000 );

var idNose = charIDToTypeID( "Nose" );

var idPrc = charIDToTypeID( "#Prc" );

desc17.putUnitDouble( idNose, idPrc, 0.000000 );

var idAntA = charIDToTypeID( "AntA" );

desc17.putBoolean( idAntA, false );

var idTrnS = charIDToTypeID( "TrnS" );

var desc19 = new ActionDescriptor();

var idNm = charIDToTypeID( "Nm " );

desc19.putString( idNm, "Linear" );

var idShpC = charIDToTypeID( "ShpC" );

desc17.putObject( idTrnS, idShpC, desc19 );

var idlayerConceals = stringIDToTypeID( "layerConceals" );

desc17.putBoolean( idlayerConceals, true );

var idDrSh = charIDToTypeID( "DrSh" );

desc16.putObject( idDrSh, idDrSh, desc17 );

var idLefx = charIDToTypeID( "Lefx" );

desc15.putObject( idT, idLefx, desc16 );

executeAction( idsetd, desc15, DialogModes.NO );




このコードは何をすると思いますか? 「DrSh」という名前でわかるように、ドロップシャドウがレイヤーに追加されます。 Photoshopの内部では、GUIのコントロールはまさにそれと呼ばれていると思います。

しかし、このコードを実行することで、機能することがわかります。

executeActionは、ダイアログをユーザーに表示し、そのジョブをサイレントに実行できることを確認できます(これにより、最後のパラメーターが決定されます)。 ID-shniki自体はどこにも記述されていません。それらについてのみ推測できます(CS6で何が起こるかについても)。

それでも、ログアクションの機能は非常に興味深いものです。本当に必要な場合は、自分でスクリプトをすばやくアップロードできます。



その他のスクリプト



同時に、これらの関数を作成しました。 興味がある場合は、 pastebinの同じスクリプトでそれらを見ることができます。



興味深い事実

結論



APIはおいしいです。 しかし、ブレンドオプションのサポートの欠如は非常に憂鬱です。 それらが必要な場合-怖いコードを台無しにする必要があるという事実に備えてください。 必要なもの(ほとんどの場合、バッチ処理で必要なもの)が画像をフレーム化することだけである場合、ImageMagickはこの場合より高速ではるかに便利になると思います。



+ /-


プラス フィルター、ヒストグラム

プラス RAW

プラス Photoshopのようなカラープロファイル

プラス javascriptは、ほとんどの人が理解できる便利な言語です

プラス 例付きのドキュメント

マイナス ブレンドオプションの欠如

マイナス Photoshopは動作する必要があります/ *突然* /

マイナス かなりゆっくり



読む



Adobe Photoshop Scripting-公式リソース

Photoshopのスクリプティング-Photoshopでの廃棄に関する小さなながらも有用なチュートリアル

PS-Scripts -Photoshopのスクリプトに関するフォーラム



考える



演習として、本当に便利なスクリプトを提案します:写真のロゴが写真と同じ配色で追加されていることを確認します-たとえば、青黄色の写真の場合は青または黄色:これにより、ロゴが写真の全体的な色と雰囲気を損なわないようにします。 ロゴは色、つまり 青を青にしないでください。 さらに、ロゴが草のような表面にない場合はクールです。別のコーナーに移動したり、塗り直したりできます。



All Articles