2月 252015
 
Pocket

Magick.NETでのカラマネAPIをかる~く調べたので。。
ImageMagick 自体はあまりよく知らない。

サンプルコード : veigr/MagickNETColorManagementSample · GitHub

使うクラスはだいたいこんな感じ(必要部分以外省略)。

ICCプロファイル

  • ColorProfileクラスを使う
  • ファイルパス、byte配列、Streamで初期化可能
  • Nameプロパティはプロファイルの種類であり、常に中身は”icc”になる予感
    • もしかしたら”icm”もあるかも?
    • readonly
  • ImageProfileクラスを親に持っているが、そちらのコンストラクタを使用してAddProfile()しても正常に動作しない
    • 何のためのpublicコンストラクタなのか不明
    • ImageProfileクラスのコンストラクタではNameプロパティを指定できる
  • ColorProfileクラスのstaticプロパティに、ライブラリ内臓リソースとしてICCプロファイルが幾つか設定されている
    • cprtタグを見ると、sRGBのみHP製で、後は全部Adobe製
    • ライセンス的にどうなってるのか気になる。Adobeのはエンドユーザー用とは異なるライセンスだったと思うが、条文長すぎて読んだこと無い。

[csharp mark=”7″]
// プロファイルフォルダのパスはICM APIのGetColorDirectory()で取得できる
const string profilesPath = @”C:\Windows\System32\spool\drivers\color”;
var profiles = Directory.GetFiles(profilesPath);
// プロファイル名を保持したかったら、別のクラスを用意する必要がある
var localProfiles = profiles
.Where(x => Path.GetExtension(x) == “.icc” || Path.GetExtension(x) == “.icm”)
.Select(x => new ColorProfile(x))
.ToArray();
[/csharp]

色変換

  • MagickImageクラスのAddProfile()メソッドで変換する
  • プロファイルをAddProfile()すると、その画像は新しいプロファイルに関連付けられる
  • AddProfile()時に既存の埋め込みICCプロファイルがある場合、既存ICCプロファイル→新たなICCプロファイルへと色変換が行われ、既存ICCプロファイルは破棄される
    • 異なる種類(name)のプロファイルなら複数持つことが可能
    • つまり1種類につき1つしか持てない
  • ICCかICMプロファイル同士の場合のみ色変換される
    • Exif等が付いてたとしても、ICCプロファイルが埋め込まれてない場合は、変換先ICCプロファイルをAddProfile()しても色変換は行われない
  • 埋め込みICCプロファイルの有無は、GetColorProfile()メソッドがnullを返すかどうかで確認できる
    • ExifやIPTCプロファイルなどの取得は、GetExifProfile()といった別メソッド
    • GetProfile()メソッドは引数でICCなのかExifなのかとか指定する感じ
    • どの種類のプロファイルがくっついてるかはProfileNamesプロパティで確認できる

[csharp mark=”7″]
using (var image = new MagickImage(filePath))
{
// 代替プロファイルとしてsRGBを指定
if(image.GetColorProfile() == null)
image.AddProfile(ColorProfile.SRGB);
// 埋め込みプロファイルからディスプレイプロファイルへ変換
image.AddProfile(displayProfile);
// BitmapSourceに変換(内部的にBitmapSource.Createで作成されているので埋め込みプロファイルは持たない)
return image.ToBitmapSource();
}
[/csharp]

黒点の補正

  • MagickImageクラスのBlackPointCompensationプロパティで指定可能
  • 目的の変換 ( AddProfile() ) の前に指定しないとダメ

[csharp mark=”3″]
using (var image = new MagickImage(filePath))
{
image.BlackPointCompensation = true;
if(image.GetColorProfile() == null)
image.AddProfile(ColorProfile.SRGB);
image.AddProfile(displayProfile);
return image.ToBitmapSource();
}
[/csharp]

AdobeRGB → USWebCoatedSWOP (Relative) の図

レンダリングインテント

  • MagickImageクラスのRenderingIntentプロパティで指定可能
  • 目的の変換 ( AddProfile() ) の前に指定しないとダメ

[csharp mark=”3″]
using (var image = new MagickImage(filePath))
{
image.RenderingIntent= RenderingIntent.Relative;
if(image.GetColorProfile() == null)
image.AddProfile(ColorProfile.SRGB);
image.AddProfile(displayProfile);
return image.ToBitmapSource();
}
[/csharp]

Matrixプロファイル同士の変換

アプリで何を指定しようが基本的に”相対的”になるという話。

LStar-RGB (D50/Matrix) → sRGB (D65/Matrix) の図

古いCMM (ICC v4以前?) での”絶対的”の話

Apple CMM や Microsoft CMM だと、Matrix – Matrixプロファイル変換で絶対的を選んだ場合に、2つのプロファイルの白色点が違うと、色が変わるという話。
※CS2以降のAdobe ACE および Magick.NET 7 では色は変わらない

LUTプロファイルの話

AdobeRGB(Matrix) → USWebCoatedSWOP (LUT/B2AxTag 3種あり) の図

 Leave a Reply