PDFに含まれている特色の情報を抜き出そうとした話

# はじめに
自分用のメモです。
やったことの証跡を残しておくか、的なゆるい気持ちで書いています。
加えて、少し基礎部分の復習なども兼ねています。

# やりたいこと
タイトルの通りです。

PDFにCMYK以外の特色が指定されているかどうかを調べたい！

## PDF？
PDFは紙に印刷するのと同じ状態のイメージを保存するためのファイル形式です。
Portable Document Formatの頭文字を取っています。
Adobeが開発したフォーマットで、一般的・・・だと思います。

「最終的に印刷したいデータはPDF」
「配布資料をどの環境でも同じように見えて欲しいからPDF」

といったところでしょうか。
私も「Windowsのパワポで作ったけど、MacBookProでプレゼンするからPDFにしとくか」みたいな使い方をたまにします。
keynoteだとずれたりしますが、PDFなら安心。（ただし、アニメーションは動かない）

## CMYK？

まず色の基本から。

|  |rgb  |cmy  |
|---|---|---|
|タイプ|加法混色（色を混ぜると白に近く）|減法混色（色を混ぜると黒に近づく）|
|別名|光の三原色|色の三原色|
|色|R（Red:赤）<br>G（Green:緑）<br>B（Blue:青）|C（Cyan：シアン）<br>M（Magenta：マゼンタ）<br>Y（Yellow:イエロー）|

CMYではなく、なぜCMYKかというと、印刷上の理由があります。

「理論上はCMYで黒を表現できるはずだが、実際には綺麗な黒にならないから」
「最初から黒インクを使っておけば黒を表現するためのインク量が少なくて済むから」

ということらしいです。

ちなみにKは黒（***K***uro）とかBlac ***k***ではなく、***K***eyPlateの頭文字らしいです。
とは言うものの、「まぁKといったら黒（墨）なんでしょ」くらいの認識でいます。

この辺りのことは少し調べればちゃんとした記事がたくさんありますので、この辺で。

### why CMYK?
テレビとかスマホの画面のように、自ら光を発するような場合はRGBで表現されます。

では紙は？
発光しますか？
テカテカした紙とかはあるにしても、紙自体は発光していませんよね。
というわけで、紙は直接発光しませんが、紙に反射した光を人の目は捉えているわけです。
この時に、全ての色を反射させると白になるので、特定の色を吸収する（反射させない）と様々な色を表現できます。

「人の目に赤（R）を認識させる」という例を元に考えてみます。

* RGB（PCとかテレビとか）の場合
    * 赤色（R）の光（波長）を発生させて、目に届ける
* CMYK（紙とか）の場合
    * イエロー（Y）とマゼンタ（M）を使って赤以外の光を吸収することにより、赤色を反射させて目に届ける

## 特色？
CMYKで表現できない色です。
金色・銀色・パステルカラーとか。蛍光色なんかも。
基本的に印刷代が高くなるので、昨今は減少傾向なのかしら。
書籍だと美術本・写真集、雑誌だと特別号、あとは結婚式の招待状とか「ここぞ」という時に使ったりします。
雑誌の名前だけは毎回使っているところもあるようです。

ちなみに、指定するとしても1つがほとんどで、多くて2つくらいです。
印刷機的にもそれくらいの方がハード的にも調整しやすかったりして、都合がいいみたいですね。

# 本題

ようやく本題です。

あくまで今回私が色々考えて試したのは以下の5つですが、それ以外にも方法はあると思います。
具体的にはnpmでそれっぽいライブラリを探して、NodeJSを使ってどうにかできないか調べたり、とか。（思いついたけど調べなかったので載せていません）

また、私が諦めた手法でも、時間をかければできたり、頑張ればできたりするものもあったかもしれません。

## 1. InDesign+ExtendScript

* メリット
    * 色分解したデータがちゃんととれる
* デメリット
    * InDesign、おっっっもい（主観）
    * 判定のためだけにInDesign起動させるのどうなの？
    * っていうか、InDesignが入っている前提にするのってどうなの？

参考までにコードを。
このコードだと不完全ですが、`res`から必要なデータを抜けば数もわかります。
ちゃんとInkというクラスがあって、名前が取れる。ふつくしい（うっとり）。

ただ、InDesignを開くコストが重いという理由で却下されました。

```ts:index.ts
(function () {
	// todo 他ファイルにしちゃってたんで載せるの省略しますが、ここでファイルを開きます
	const inks: Inks = (<any>app.documents[ 0 ]).inks;
	const len = inks.length;
	let res = "";
	for ( let i = 0; i < len; i++ ) {
		const ink: Ink = inks[ i ];
		res += ink.name + "\n";
	}
	alert( res );
	alert( "complete" );
})();
```


## 2. Acrobat+ExtendScript

* メリット
    * （頑張れば）特色数は取れそう
* デメリット
    * （私の考えたやり方をするなら）作業PC全てにプリフライトを設定する必要がある

### ぐち

この手法、調査開始前はもっとも期待していた方法です。
すぐできると思っていました。

#### そもそもドキュメントが少ない

よく見ていたのは「[Acrobat DC SDK Documentation](https://help.adobe.com/en_US/acrobat/acrobat_dc_sdk/2015/HTMLHelp/#t=Acro12_MasterBook%2FIntroduction_Help_TitlePage%2FAbout_This_Help.htm)」です。
日本語のリファレンスは古くて載っていない機能とかあります。

#### Acrobatのスクリプトでできることが少ない

他のスクリプトは割と実際のアプリ上でできることはスクリプトでもできるのに、Acrobatはできることが少ないと思いました。

だって、Acrobatの機能で、出力プレビューとかすると簡単に特色の有無が見れるんですよ？
PDFの該当パラメータを楽に取ってこれるメソッドとかあるに違いないと思うじゃないですか。

でも、調べども調べども見つからず。

それなら、とスクリプト上でプリフライトを作って判定しようと思っても、細かいプリフライトの設定はできない。
プリフライトを実行してDoc.report()で取得したレポートも、実際に出力されるレポートとは異なる。

#### プリフライトをどこに置けばいいのかわからない
色々ありましたが、私が考えたのは以下の手順です。

1. 特色数を調べるプリフライトを作る
2. アプリ起動時に、該当プリフライトがなければ作業PCに自動で設定する
3. そのプリフライトを使うスクリプトを起動してチェックする

私が途中で諦めたのは2のところです。
スクリプトとか、プリセット（joboptions）はローカルのどこに置けばいいのかわかるんですけど、プリフライトはわからなかったです。

なんにしても、AcrobatのスクリプトでimportProfileとかそんなメソッドがあれば解決できたのになぁ、というのが感想です。

## 3. Acrobat（Droplet）+スクリプト

* メリット
    * （頑張れば）ちゃんとデータがとれる
* デメリット
    * 作業PC全てにDropletを設置する必要がある
    * Droplet実行時のサクセスフォルダとエラーフォルダを作業PCに合わせて設定する必要がある
    * Dropletによるレポート出力を待つ必要がある
    * 出力されたレポートを解析して、特色数を数える必要がある
    * といった感じで、ともかく手順が増える

「頑張ればできる」という感じですね。
やることが増えるので、あまりやりたくないです。
どうしても必要になったらこの手を使ったかもしれませんが、そこまでするつもりはないので却下となりました。

## 4. ExtendScriptのみ（PDFの中身をスクリプトで調べる）

* メリット
    * jsファイルだけで済むから他アプリいらない
* デメリット
    * データによっては取得に失敗する
        * そもそも「PDF」と一括りにしているが、Photoshopで書き出したものとか、圧縮したものとか、最適化したものとか、なんか色々あって心を折られる

時間制限であまり調べられなかったのですが、PDFの仕様とか諸々をしっかり読み込めばできたのかもしれません。

ファイルを1行ずつ読み込んで、`ColorantOrder`とか`PlateNames`を探して取得してパースしました。
ColorantOrderとかはファイルの後方にあることが多かったので、そちらから探すようにしたりとか地味に工夫はして見ました。

ただし、私に与えられた時間内では、PDFファイルによっては取得できないデータがあったので却下となりました。

## 5. 運用回避

* メリット
    * コードの実装が不要
* デメリット
    * ユーザが一度PDFを開く必要がある


Acrobatを開いて出版プレビューで確認する方法です。
***これが確実ですよね***、ということになりました。