めとべや東京 #7 で話したやつです。
2月 212015
めとべや東京 #7 で話したやつです。
そのうちまとめるつもり。
System.Windows.Media
, System.Windows.Media.Imaging
の中にちょっとだけある。ほぼWPF専用なのではないかという予感…クラス / 構造体 | 概要 |
---|---|
ColorConvertedBitmap | WICで一度だけ色変換できるBitmapSource。微妙MarkupExtensionもあるよ。 |
ColorContext | ICCプロファイル的なやつ。 |
Color | sRGB/scRGBカラーを扱う。挙動が微妙なこともあり、カラマネ的には役に立たない可能性が。 |
BitmapFrameと各種Encoder/Decoder | 画像ファイルを取り扱うクラス群。画像プロファイルも読み書きしてくれるっぽい。中身はWICの模様。 |
System.Windows.Media
がICMに対応して、System.Windows.Media.Imaging
がWICに対応するイメージなのかな?ColorContext
と、変換したいBitmapSource
を指定して色変換できる。BitmapSource
を継承してるので、Image.Source
とかに指定できる。IWICColorTransform
を使ってる。ColorContextHelper
を通してICMのOpenColorProfile()
とGetColorProfileHeader()
を利用している。PixelFormat
を指定して初期化することでsRGBとかscRGBのColorContext
を取得できることになっているが、実際に取得されるのは コントロールパネル>色の管理>詳細設定>デバイスプロファイル に設定されているプロファイルだったり。
GetStandardColorSpaceProfile()
を利用しているからで、sRGBのプロファイルIDを指定しているにもかかわらず上記のような結果になるという謎挙動が原因である。FromValues()
およびFromAValues()
にてColorContext
を指定できるが、これは非常にややこしいことに「指定されたColorContext」→「既定のデバイスプロファイル(大抵はsRGB)」という変換となる。
ColorContext
のRGB」を表す型なのかと思ってたら全然違った。ComputeScRgbValues()
というprivate methodの中で、PixelFormats.Bgra32
を用いて変換先ColorContext
を初期化しており、このソースを見る限りは本当はsRGBを変換先とするつもりっぽいのだけど、上記ColorContext
の謎挙動により既定のデバイスプロファイルが変換先となってしまっている。ColorTransform
というinternal classを使っている。それ使わせてくれよ…
ColorTransform
は、ColorTransformHelper
を経由してICMのCreateMultiProfileTransform()
とTranslateColors()
をやってくれるクラス。System.Windows.Media.Imaging
は大体WICと同じ雰囲気っぽい?IWICColorTransform
とかは使わせてくれない微妙な感じ…BitmapFrame.Create
時などにBitmapCreateOptions.IgnoreColorProfile
を指定していないと、埋め込まれた画像プロファイルからsRGB (これも同様にデバイスプロファイルかも知れない) へ変換される
ColorContexts[0]
はsRGBに置き換えられず、そのままであるColorConvertedBitmap
に食わせると、二重に変換されたりして悲しい思いをするBitmapCreateOptions.IgnoreColorProfile
を指定した場合、元のカラースペースを保持した状態で読み込まれるBitmapFrame.Create
する際にBitmapCreateOptions.PreservePixelFormat
を指定していない場合も、RGB PixelFormatへ自動変換される
ColorContexts[0]
はCMYKプロファイルのままであるBitmapCacheOption.None
以外で読み込んだ場合、その時に指定されたBitmapCreateOptions
で画像がキャッシュされ、再読込時のBitmapCreateOptions
は無視される
BitmapCacheOption.OnLoad
が必要な点に注意EnumDisplayMonitors()
とGetMonitorInfo()
でMONITORINFOEX
取得CreateDC()
でデバイスコンテキスト取得GetICMProfile()
でプロファイルパス取得