ExtendScriptを使ってPhotoshop用のスクリプトを組むときに使った（調べた）こと色々

# はじめに
私が必要に応じて調べた分だけです。
メソッド自体は調べても、私にとって不要だった引数は説明できないので触れません。

今後さらに調べたら追記していこうと思います。

# 環境
Adobe Photoshop CC 2018

# Photoshop上で取り扱う単位を切り替える

`app.preferences.rulerUnits`に使いたい値を設定する。

|指定可能値  |
|---|
|Units.PIXELS|
|Units.INCHES|
|Units.CM|
|Units.MM|
|Units.POINTS|
|Units.PICAS|
|Units.PERCENT|

```ts:（例）Photoshop内で使用する単位をミリメートルにする
app.preferences.rulerUnits = Units.MM;
```

Photoshop上で「環境設定 > 単位・定規」で開く環境設定において「単位 定規」の値を設定することと同じ。

指定すると、`ColorSampler.move()`とか`Document.crop()`とかの単位が変わる。
例えば、`ColorSampler.move( [ 1, 1 ] )`は、

* Units.MM 指定の場合 ➡︎　x座標1mm、y座標1mmの色情報を取得
* Units.PIXELS 指定の場合　➡︎ x座標1ピクセル、y座標1ピクセルの色情報を取得

スクリプト上で設定した値は次にPhotoshopを使うときにもそのまま残ってしまうので、それが嫌なら処理後に設定前のパラメータを再設定する。


# ドキュメントを閉じる
documentオブジェクトのcloseメソッドを利用する。


||型|説明|
|---|---|---|
|第一引数|string|閉じ方の指定|

|第一引数の指定可能値|説明|
|---|---|
|SaveOptions.SAVECHANGES|保存して閉じる|
|SaveOptions.DONOTSAVECHANGES|保存せずに閉じる|
|SaveOptions.PROMPTTOSAVECHANGES|保存するかどうかユーザに確認する|

```ts:（例）アクティブなドキュメントを、保存確認せずに閉じる
app.activeDocument.close( SaveOptions.DONOTSAVECHANGES );
```

```ts:（例）４つ目のドキュメントをアクティブかどうかに関係なく、保存確認せずに閉じる
app.documents[3].close( SaveOptions.DONOTSAVECHANGES );
```

```ts:（例）保存確認せずに開いているドキュメントを全て閉じる
const len = app.documents.length;
for ( let i = 0; i < len; i++ ) {
	app.documents[ 0 ].close( SaveOptions.DONOTSAVECHANGES );
}
```

# ファイルを開く

```ts:（例）pathで指定されたファイルが存在していたら開く
const file = new File( path );
if ( file.exists === false ) {
	throw new Error("pathに該当するファイルが存在しません。");
}
app.open( file );
```

# Documentのチャンネルを他のDocumentのチャンネルにコピー（複写）する
Channelオブジェクトのduplicateメソッドを使う。

||型|説明|
|---|---|---|
|第一引数|Document|<オプション><br>対象ドキュメント<br>指定しない場合は同一ドキュメントにコピー|

```ts:（例）fromDocの先頭チャンネルをtoDocにコピーする
fromDoc.channels[ 0 ].duplicate( toDoc );
```

toDocのチャンネル末尾に追加されているので、`toDoc.channels[toDoc.channels.length-1]`とかで該当チャンネルが取れる。

コピー先のドキュメントはアクティブである必要がある。
上記の例の場合だと、toDocがアクティブでないとエラーになる。

# 指定範囲を切り抜く
Documentオブジェクトのcropメソッドを使う。

||型|説明|
|---|---|---|
|第一引数|[number, number, number, number]|切り抜き領域<br>x1,y1,x2,y2の順に指定|
|第二引数|number|<オプション>回転角|
|第三引数|number|<オプション>幅|
|第四引数|number|<オプション>高さ|

```ts:（例）アクティブなドキュメントをピクセルで指定して切り抜く
app.activeDocument.crop( [1000, 1000, 11000, 11000] );
```

処理としてはPhotohsopの切り抜きツールに該当。

私のこれまでの経験だと、4つ指定するときは`(X座標,Y座標,幅、高さ)`が多かったけど、cropで指定する場合は`(開始X座標,開始Y座標,終了X座標,終了Y座標)`だったので一瞬戸惑った。

また、「切り抜く」の英語は「trim（トリミング）」だと思っていたら「crop」だった。
参考：[「trim」と「crop」の違い | グラフィックデザイナーのための英語講座](https://ameblo.jp/fishtailstudio/entry-11519140139.html)

# 画像解像度の変更
DocumentオブジェクトのresizeImageメソッドを使う。

||型|説明|
|---|---|---|
|第一引数|number|<オプション><br>幅|
|第二引数|number|<オプション><br>高さ|
|第三引数|number|<オプション><br>解像度|
|第四引数|ResampleMethod|<オプション><br>再サンプルの指定|


|第四引数の指定可能値  |説明  |
|-------|-------|
|ResampleMethod.NONE|なし|
|ResampleMethod.NEARESTNEIGHBOR|ニアレストネイバー法（ハードな輪郭）|
|ResampleMethod.BILINEAR|バイリニア法|
|ResampleMethod.BICUBIC|バイキュービック法（滑らかなグラデーション）|
|ResampleMethod.BICUBICSHARPER|バイキュービック法 - シャープ（縮小）|
|ResampleMethod.BICUBICSMOOTHER|バイキュービック法　- 滑らか（拡大）|
|ResampleMethod.BICUBICAUTOMATIC|バイキュービックを自動で判定？|
|ResampleMethod.AUTOMATIC|自動|
|ResampleMethod.PRESERVEDETAILS|ディテールを保持|

```ts:（例）幅と高さは変更しないで、バイキュービック法を使って解像度300に変更
app.activeDocument.resizeImage(
	undefined, undefined,
	300,
	ResampleMethod.BICUBICAUTOMATIC
);
```

```ts:（例）高さ1200に合わせて幅は成り行きで変更する
app.activeDocument.resizeImage( undefined, 1200 );
```

Photoshop上では「イメージ > 画像解像度...」を実行したのと同じ。
単位は`rulerUnits`で指定した値が使われる。

# 色をCMYKからRGBに変換する
DocumentオブジェクトのchangeModeメソッドを使う。

||型|説明|
|---|---|---|
|第一引数|ChangeMode|変更したいカラーモード|
|第二引数|?|<オプション><br>オプション|


|第一引数の指定可能値|説明|
|---|---|
|ChangeMode.GRAYSCALE|グレースケール|
|ChangeMode.RGB|RGBカラー|
|ChangeMode.CMYK|CMYKカラー|
|ChangeMode.LAB|Labカラー|
|ChangeMode.BITMAP|ビットマップ|
|ChangeMode.INDEXEDCOLOR|インデックスカラー|
|ChangeMode.MULTICHANNEL|マルチチャンネル|

```ts:例（アクティブドキュメントをRGBカラーに変更する）
app.activeDocument.changeMode( ChangeMode.RGB );
```

Photoshop上の「イメージ > モード」で変更することと同じだと思っている。

# 色をCMYKからRGBに変換する（カラープロファイル）
DocumentオブジェクトのconvertProfileメソッドを使う。

||型|説明|
|---|---|---|
|第一引数|string|使用するカラープロファイル名|
|第二引数|Intent|マッチング方法|
|第三引数|boolean|<オプション><br>黒点の補正を使用|
|第四引数|boolean|<オプション><br>ディザの使用|


|第二引数の指定可能値|説明|
|---|---|
|Intent.PERCEPTUAL|知覚的|
|Intent.SATURATION|彩度|
|Intent.RELATIVECOLORIMETRIC|相対的な色域を維持|
|Intent.ABSOLUTECOLORIMETRIC|絶対的な色域を維持|

```ts:（例）sRGBのプロファイルを使い、マッチング方法は彩度を選択して変換
app.activeDocument.convertProfile(
	"sRGB IEC61966-2.1",
	Intent.SATURATION
);
```

Photoshop上の「編集 > プロファイル変換」で変更することと同じだと思っている。

# PDFを保存
DocumentオブジェクトのsaveAsメソッドを使う。

||型|説明|
|---|---|---|
|第一引数|File|保存するファイル情報|
|第二引数|PDFSaveOptions|<オプション><br>保存オプション<br>※PDFで保存したいので、PDFSaveOptionsを使う|
|第三引数|boolean|<オプション><br>複製を保存するかどうか|
|第四引数|Extension|<オプション><br>保存時の拡張子を大文字にするか小文字にするかとか|

PDFSaveOptionsについては指定可能な値が多いので、時間があるときにまとめる。

```ts:（例）PDFオプションを指定して、デスクトップにsample.pdfという名前でアクティブなドキュメントを保存する
const pdfOptions = new PDFSaveOptions();
pdfOptions.encoding = PDFEncoding.JPEG;
pdfOptions.jpegQuality = 8;
pdfOptions.optimizeForWeb = true;
pdfOptions.PDFCompatibility = PDFCompatibility.PDF13;
pdfOptions.PDFStandard = PDFStandard.NONE;
app.activeDocument.saveAs( new File("~/Desktop/sample.pdf"), pdfOptions );
```

# JPEGを書き出し
DocumentオブジェクトのexportDocumentメソッドを使う。

||型|説明|
|---|---|---|
|第一引数|File|保存するファイル情報|
|第二引数|ExportType|<オプション><br>WEB用か、イラストレーターへのパス書き出しか|
|第三引数|ExportOptionsSaveForWeb|<オプション><br>保存オプション<br>※JPEGで保存したいのでExportOptionsSaveForWebを使う|

ExportOptionsSaveForWebについては指定可能な値が多いので、時間があるときにまとめる。

```ts:（例）オプションを準備して、デスクトップにsample.jpegという名前でアクティブなドキュメントを保存する
const expOptions = new ExportOptionsSaveForWeb();
expOptions.format = SaveDocumentType.JPEG;
expOptions.quality = 80;
app.activeDocument.exportDocument( new File("~/Desktop/sample.jpeg"), ExportType.SAVEFORWEB, expOptions );
```

# アクティブなドキュメントを切り替える（2019/11/1追記）
実際のPhotoshopでいうと、編集中の画像を切り替えること。
これをしないと、コピーとかペーストの対象はアクティブにしておかないと動かないことが多い。

以前も使っていたのに、今回使い方を忘れていて調べたから載せておきます。

```jsx
app.activeDocument = target;
```

`target` は適当に。
既に開いているドキュメントを対象とするなら

```jsx
const target = app.documents[i]
```

新たにファイルを開いてドキュメントとするなら

```jsx
const target = app.open( new File( "C:/hogehoge.psd" ) )
```

# 全範囲選択してコピー（2019/11/1追記）

```jsx
hogeDoc.selection.selectAll();
hogeDoc.selection.copy();
```

# チャンネルにペースト（2019/11/1追記）
一つ上のコピーが終わっている前提で、その後の手順は以下の通り。

1. ペーストしたい対象ドキュメントをアクティブにして、
2. 対象ドキュメントのペースト対象にしたいチャンネルを有効にして
3. 対象ドキュメントにペースト

コードは次のようになる。

```jsx
app.activeDocument = hogeDoc;
hogeDoc.activeChannels = [hogeDoc.channels[i]];
hogeDoc.paste();
```

# 時間計測
`new Date()`は使えるので、これを使う。
下記スクリプトでは、最終のms秒をアラートで表示。

```jsx
const start = new Date();

// 処理

const end = new Date();
alert( ( end.getTime() - start.getTime() ).toString() );
```

# その他
特定のメソッドによる機能だけでは実現できなかった作業の備忘録。

## CMYKは保持したまま、あるチャンネルを同一ドキュメントにコピーして元チャンネルは白紙にする

```ts:（例）先頭チャンネルを同一ドキュメントにコピーして、先頭チャンネルをclearする
const channel: Channel = doc.channels[ 0 ];
channel.duplicate( doc );
doc.activeChannels = [ channel ];
doc.selection.selectAll();
doc.selection.clear();
doc.selection.deselect();
```

Channelオブジェクトにはremoveメソッドもあるが、削除したらカラーモードがCMYKではなくなってしまった。
そのため該当チャンネルだけをアクティブにして、全選択し、クリアする。
必要ならその後、アクティブにしたいチャンネルを再設定する。