とりあえずのGDI/GDI+編最終回となる今回はSusieプラグインをネタに画像の扱いについて軽く解説していきます。

Susieプラグインとカラーマネジメントの現状

ホストアプリケーション(画像ビューアなど)からSusieプラグインを利用するために必要な手順やルールなどをまとめたSusie Plug-in API(参考)には、画像ファイルに埋め込まれたICCプロファイルについての取り決めがなく、公式にはプラグインから埋め込みプロファイルを取得する方法は存在しないことになっています。

Susieプラグインが必須のアプリケーションではカラーマネジメント表示に対応していない、また必須でなくカラーマネジメント対応を謳うアプリケーションであってもSusieプラグイン使用によるファイル読み込みでは何かしら制限がある、というのはそういう背景によるものです。それならば、ホストに渡す前にあらかじめ画像データをモニタのカラースペースに変換してしまえば実質的にカラーマネジメント表示ができるではないか……ということでそれをやって見せたのが「カラーマネージメント代行 Susie Plug-in」であるというのは皆さんご存じであろうと思います。

即効性があって愛用のプラグインをそのまま使い続けられることから有用であることは間違いありませんが、ホスト側に渡る時点で既に変換が適用されてしまっている(変換前のデータに触ることができない)がために、マルチモニタ対応やプリンタ出力へのカラーマネジメント、また画像編集・ファイル変換系のアプリケーションには適さないというトレードオフも抱えていることは忘れてはなりません。

ホストとプラグインの両面からカラマネ対応に

さて、Susie Plug-in APIではプロファイルを渡す方法が提供されていないというのはその通りなのですが、実際にはひとつ抜け道が存在しています。

プラグインで読み込み・展開された画像データはDIB(Device Independent Bitmapの略。ここではWindows GDIにおけるDIBを指すものとします)としてアプリケーションに引き渡されます。このDIBのフォーマットは何度か改定されていて、現行の仕様ではプロファイルの埋め込みが可能となっているため、これを利用すればホストアプリケーションにプロファイルを引き渡す目的を達成可能です。

Note:「現行の仕様」とは書いたものの、実のところその仕様はWindows 98/2000の世代、つまり15年以上前に定められたものです。また、BMPファイルの中身はほぼDIBそのものなので、仕様上はBMPファイルにもICCプロファイルを埋め込むことが可能です(ただし対応しているアプリケーションはほとんどない)。

プラグイン

詳細はDIBについて日本語で読める解説がありますのでそれらを参照していただくとして、ポイントをまとめると、

  1. ヘッダ部分にはBITMAPV5HEADER構造体を使用する
  2. ヘッダのbV5CSTypePROFILE_EMBEDDEDを指定し、bV5ProfileDatabV5ProfileSizeに適切な値をセットする
  3. ヘッダに続けてプロファイルの生データをまるごと配置する

ということになります。画像ファイルからプロファイルを取り出す方法については有名どころのフォーマットであれば入出力ライブラリ・フレームワークでAPIが用意されていると思いますので、それぞれのマニュアル・リファレンスを参照してください。

ホスト

さて、実際に表示を行うホスト側ですが、GDIで描画する分には非っ常ーーーーに簡単です。

  1. 描画対象のデバイスコンテキストに対してICMをオンにする(SetICMMode関数)
  2. SetDIBitsSetDIBitsToDeviceStretchDIBitsのいずれかの関数を使ってDIBを描画する

……これだけ?

はい、これだけです。

描画にGDIが使えない(使いたくない)場合や、デバイスへの出力・表示ではなく画像処理の文脈で変換結果をDIBまたは生のビットマップデータとして保持したいような場合には、ヘッダを参照してプロファイルにアクセスし、ICMの低レベルAPIなり外部の変換エンジン(Little CMSなど)なりで変換することになるでしょう。あるいはDIBSectionを割り当てたメモリデバイスコンテキストに対してSetICMProfile関数とDIBits系関数で変換してしまってもよいかもしれません。

ICMの低レベルAPIやLittle CMSを用いた変換については、反響をみて機会があれば別記事で紹介したいと思います。

サンプル

C#で書かれたフォームアプリケーションのソースコードとバイナリをBitbucketにて公開しています。

Susieプラグインはサンプルのバイナリと同じフォルダにコピーし"loader.spi"にファイル名を変更してください。プラグインの呼び出しにP/Invokeを使用していますので、ファイル名は固定で同時に扱えるプラグインはひとつのみとなります。

GDICMTest03_1

ICMをオフにして描画している状態のスクリーンショット。このスクリーンショット画像をダウンロードしてRGB値を拾ってみると記載の数値と同じであることが分かります。

GDICMTest03_2

ICMオンで描画したスクリーンショット。RGBを入れ替えたテスト用のプロファイルが埋め込まれているためこのような表示になっています。

GDICMTest03_3

プラグインからプロファイルが渡されない(旧式のDIBヘッダが使われている)場合にはICMを切り替えるチェックボックスが無効になります。これはプラグインが埋め込みプロファイルに対応しているかどうかを判別しやすいようにしてあるもので、GDIの仕様上にオンにできないという意味ではありません。

ソースコードの方は、解説の通りSetICMMode関数が出てくる以外はカラーマネジメントに関わる部分がまるでないのがわかります。それで終わってしまうのもつまらないかと思いますので、時間のある方は前回のお題であるマルチモニタ対応を追加してみるとよいでしょう。

まとめ

以上のように、SusieプラグインやSusieプラグイン対応ホストにおける基本的なカラーマネジメント対応は案外簡単にできるというのはおわかりいただけたのではないでしょうか。もし、愛用のSusieプラグインやホストアプリケーションがあるのでしたら、作者に対応を依頼してみるのもよいでしょう。もちろん、あなた自身が作者であるなら今すぐにでも対応されることをお勧めします;-)

余談ですが、今回の記事で紹介した内容を踏まえ、実際に作成されたホストアプリケーションがsusico(すじこ)です。試供品扱いながらSusieプラグインも同梱されていますので、動作確認に活用してみてください。当記事執筆時点では、susicoの他にPictureFanもSusieプラグインからのプロファイル引き渡しに対応済みです。興味のある方はお試しを。