WPFで影の色が思い通りにならない問題と対策

もくじ

問題となる現象

WPFでは,DropShadowEffectのColorプロパティに指定した色がそのまま影の色に反映される訳ではなく,暗めの色に変換されてから表示される。

次の例は,このサイトのテーマカラーである #169632 の色を,WPF上で四角形(Border)とそのDropShadowEffectの両方に設定したもののキャプチャ画像だ。

同じ色を設定したにも関わらず,四角形と影とで実際の色が異なる。

四角形には正確に色が反映されているが,影は暗めに調整されてしまっている。

いつも暗めに調整されるかというとそうでもなく,白(#FFFFFF)に設定すると実際の影の色も真っ白になるからますます訳が分からない。

これでは色の微調整が正確に行えない。

原因

DropShadowEffectのColorプロパティに設定された色は内部で勝手にscRGB色空間に変換されている。

具体的にどのような変換かというと,R,G,Bそれぞれに対してガンマ補正がかけられている。

下の図の,「CRT gamma 2.2」と書かれている,下にカーブした曲線になるように値が変換されているのだ。

これによりほとんどの色は暗めに変換されるが,真っ白の場合は真っ白のまま,真っ黒の場合は真っ黒のままという不思議な挙動となっていた。

対策

ガンマ補正がかけられるのなら,それを見越した色に設定すればよい。

例えば,先ほどの例で四角形に対して #169632 を設定した場合は,影に対して #53CA7A を設定すると同じ色として表示される。

こんな風に。

これで,影の色を思い通りに設定できるようになる。

・・・でも,どうやって?

WPFでは難しい計算を考える必要はない。

C#で書く場合

Color構造体のFromScRgbメソッドを使って次のようにすれば影に設定すべき色が得られる。

// 四角形に設定する色
Color rectColor = Color.FromRgb(22, 150, 50);

// 影に設定する色
Color shadowColor = Color.FromScRgb(1.0f, rectColor.R/255.0f, rectColor.G/255.0f, rectColor.B/255.0f);

コードビハインドやViewModelクラス内にこの処理を記述すると問題がある場合は,この処理を行うコンバーターを作成し,XAML内で利用すればよい。

コンバーターの作り方についてはこちらで説明している。

XAMLで書く場合

XAMLで書きたい場合は次のように書く。

<Color ScR="0.086" ScG="0.588" ScB="0.196" ScA="1.0"/>

Color構造体に設定する各プロパティは0~1の小数値。

例えば,RGBではRの値が22の場合,Color構造体のScRに設定する値は

22/255 = 0.086

となる。

この計算を毎回するのが面倒な場合は,自前でコンバータをこしらえてもよいと思う。

コメントする