読者です 読者をやめる 読者になる 読者になる

みかづきブログ その3

3ヶ月つづけてみました。

JSXをつかってPhotoShopを自動化する

JavaScript

以前からJavaScriptをつかってPhotoShopを自動化できることは知っていましたが、実際にやってみたことはありませんでした。
が。本日突如発生した「すべてのレイヤーの大きさの違う画像に対して上だけトリミングしたい」という作業がめんどくさ過ぎたため、JSXでプログラムを書いてみることにしました。


今回取り扱うJSXとは

PhotoShopなどのAdobeのプロダクトを制御するためのJavaScriptです。普通のJavaScriptとほとんど変わりはないのですが、拡張子を.jsxにする必要があります
【追記1】拡張子を.jsxにしなくても動きました。
【追記2】世の中にはいろんなJSXがありますが、今回の言うところのJSXはAdobeのExtendScriptのことです。


兎にも角にもJSXを書いてみる

hello.jsx
alert("HELLO WORLD.");

上記JavaScriptに hello.jsx と名前をつけて適当な場所に保存してみましょう。
とりあえず僕はデスクトップに保存してみました。


兎にも角にも書いてみたJSXを実行してみる

f:id:kimizuka:20160802090600p:plain
ファイル > スクリプト > 参照 をクリック

f:id:kimizuka:20160802090810p:plain
先ほど保存したJSXのファイルを選択

f:id:kimizuka:20160802091141p:plain
PhotoShopで実行されアラートが表示される


もうちょっとJSXらしいことをやってみる

ドキュメントにアクセスしないとJSXっぽさがでないので、ドキュメントのサイズを表示してみましょう。

size.jsx
alert("WIDTH: " + app.activeDocument.width + " HEIGHT: " + app.activeDocument.height);

こちらのコードを実行すると、

f:id:kimizuka:20160802091707p:plain

このようなアラートが表示されます。


JSXのメソッド

こちら に大体まとまってました。

Photoshop CS自動化作戦 with JavaScript


今回つくったスクリプト

当初の目的に戻ります。
今回達成したいことは、

  1. 全レイヤーグループ内のレイヤーの上部分のみトリミング
  2. 指定したフォルダにレイヤーセット名と同じフォルダをつくる
  3. つくったフォルダにレイヤーセット毎に通し番号でトリミングした画像を書き出す

です。

trim.jsx
var ORIGINAL = { // ドキュメントサイズのオリジナルを保存
    WIDTH  : app.activeDocument.width,
    HEIGHT : app.activeDocument.height
  },
    folder          = Folder.selectDialog("書き出し先を選択"), // 書き出し先になるフォルダを選択
    layerSetsLength = activeDocument.layerSets.length; // レイヤーセットの数を取得

if (folder) { // 書き出し先になるフォルダがあるとき(キャンセルボタンを押すとfalseの方の処理になる)
  preferences.rulerUnits = Units.PIXELS; // 単位をpxに設定

  for (var i = 0; i < layerSetsLength; ++i) (function(i) {
    hidden(activeDocument.layerSets[i]);
  })(i);

  for (var i = 0; i < layerSetsLength; ++i) (function(i) {
    slice(activeDocument.layerSets[i]);
  })(i);
} else {
  alert("ERROR: 書き出し先を選択してください");
}

function hidden(layerSet) {
  var layers = layerSet.artLayers; // レイヤーセット内のレイヤーの参照を変数に保存

  for (var i = 0; i < layers.length; ++i) (function(i) {
    layers[i].visible = false; // ループでレイヤーを非表示にする
  })(i);
}

function slice(layerSet) {
  var saveFolder = new Folder(folder.fsName + "/" + layerSet.name), // 書き出し作のフォルダを作成
      options    = new ExportOptionsSaveForWeb(), // オプションを作成
      layers     = layerSet.artLayers;

  saveFolder.create();

  options.format     = SaveDocumentType.PNG; // pngで書き出し
  options.optimized  = true; // 最適化設定
  options.interlaced = false; // インターレース設定

  for (var i = 0; i < layers.length; ++i) (function(i) {
    var saveFile = new File(saveFolder.fsName + "/" + i + ".png"), // 通し番号でファイルを作成
        top      = Math.max(layers[i].bounds[0], layers[i].bounds[1]); // 左上と右上の座標を比較し大きい物をtopに収納

    layers[i].visible = true; // レイヤーを表示
    activeDocument.activeLayer = layers[i]; // レイヤーをアクティブに
    activeDocument.resizeCanvas(ORIGINAL.WIDTH, (ORIGINAL.HEIGHT - top), AnchorPosition.BOTTOMRIGHT); // 右下基準でドキュメントをリサイズ
    activeDocument.exportDocument(saveFile, ExportType.SAVEFORWEB, options); // 書き出し
    layers[i].visible = false; // レイヤーを非表示にする
    activeDocument.resizeCanvas(ORIGINAL.WIDTH, ORIGINAL.HEIGHT, AnchorPosition.BOTTOMRIGHT); // ドキュメントサイズを元に戻す
  })(i);
}

f:id:kimizuka:20160802103815p:plain

こういうPSDから、

f:id:kimizuka:20160802104101p:plainf:id:kimizuka:20160802104106p:plain

こういう画像を切り出せます。
まったく同じスクリプトを必要としている人はいないと思いますが、基本的なJSXの記法がつまっているのでためしてみると、JSXの書き方がわかるかもしれません。