午後わてんのブログ

ベランダ菜園とWindows用アプリ作成(WPFとC#)

WPFとVB.NETでカラーピッカーその3、元の色の明るさ(輝度)に合わせた別の色(色相)を選びたい

WPFVB.NETでカラーピッカーその2、HSVとRGBで色指定 ( ソフトウェア ) - 午後わてんのブログ - Yahoo!ブログ
http://blogs.yahoo.co.jp/gogowaten/14025927.html
前回6日前から
 
 

色相を変化させた時に元の色の輝度に合わせた色にする

 
色を選んでいる時に今の色のトーンっていうのかな、明るさに合わせた色を
選びたい時がある、これをある程度自動でできるようにしてみた
 
明るさの基準はHDTV形式の輝度(Y)にした
 
例えば色相30のオレンジ色(RGB(255,128,0))と同じくらいの明るさの
水色(色相180)を選びたいとき
イメージ 1
色相だけ水色の180に移動させると
 
イメージ 2
オレンジ色に比べてずいぶん明るくなる
明るさ(輝度)を変えるには彩度(S)と明度(V)を変化させればいい
今回は明度(V)を変化させて輝度を合わせるようにした
 
輝度の範囲0から255のとき
オレンジ色 163.7
水色 227.5
だったので水色の輝度をオレンジ色と同じ163.7になるまで明度(V)を下げる
 
イメージ 3
明度(V)72をまで下げると輝度164.2でだいたいオレンジ色と同じくらいの
明るさになった
 
イメージ 4
動き
輝度固定にチェックを入れると新しい色が輝度固定比較用にコピーされて
色相(H)とガンマ値以外は動かせなくなる
 
 
 
デザイン画面

f:id:gogowaten:20191025122958p:plain

 

f:id:gogowaten:20191025123009p:plain

 
 
VBコード

f:id:gogowaten:20191025123022p:plain

前回から書き加えたのが青い■のところ
 

 
 
 
RGBやHSVから輝度を求めるものが必要なので
osakana.factory - グレースケールのひみつ
https://ofo.jp/osakana/cgtips/grayscale.phtml
この辺りを参照して
 
 
イメージ 8
ColortoHDTVはColorを渡すとHDTV形式の輝度を返す関数
Colorだと0から255の整数値でちょっと大雑把かなと思って

イメージ 9
っていうDouble型の値を持つ構造体RGBをつくって小数点以下の数値も
意味があるようにして、これを利用して
 
イメージ 10
RGBtoHDTVはRGBを渡すとHDTV形式の輝度を返す関数
この関数を利用するのが
 
イメージ 11
HSVを輝度に変換する関数
HSVtoHDTVY
 
これで準備OK
'色相を変化させた時に元の色の輝度に合うV(明るさ)を返す
Private Function GetVFixedY() As Double
    Dim h As Double = sldHue.Value ’Hスライダーの値
    Dim s As Double = sldS.Value   ’Sスライダー
    Dim v As Double = sldV.Value   ’Vスライダー
    Dim b As SolidColorBrush = rectY.Fill
    Dim col As Color = b.Color      ’輝度固定比較用の色
    Dim gamma As Double = sldGamma.Value   ’ガンマ値
    Dim oldY As Double = tbkOldY.Text     ' 基準になる輝度(比較用の色)
    Dim newY As Double = HSVtoHDTVY(New HSV(h, s, v), gamma)
    Dim nv As Double

    If newY > oldY Then
       'v下げ、基準輝度を下回るまでVを1づつ下げる、下回ったら1足してから0.1づつ下げて探す
        For i As Integer = v To 0 Step -1
            newY = HSVtoHDTVY(New HSV(h, s, i), gamma)
            If newY < oldY Then
                For d As Double = i + 1 To 0 Step -0.1
                    newY = HSVtoHDTVY(New HSV(h, s, d), gamma)
                    If newY < oldY Then
                        nv = d + 0.1
                        Return nv
                    End If
                Next
            End If
        Next
    Else
       'v上げ
        newY = HSVtoHDTVY(New HSV(h, s, MaxSV), gamma)
        If newY < oldY Then
            nv = MaxSV
            Return nv
        End If
        For i As Integer = v To MaxSV
            newY = HSVtoHDTVY(New HSV(h, s, i), gamma)
            If newY > oldY Then
                For d As Double = i - 1 To MaxSV Step 0.1
                    newY = HSVtoHDTVY(New HSV(h, s, d), gamma)
                    If newY > oldY Then
                        nv = d
                        Return nv
                    End If
                Next
            End If
        Next
    End If

    Return nv

End Function
 
 
 
 
GetVFixedYは単純に比較用の元の色の輝度と今の色の輝度を比較して
今のほうが大きければ小さくなるまでVを1づつ下げて比較を繰り返す
小さくなったらVに1足してから今度は0.1づつ下げて比較を繰り返して
小さくなったらその時のVを返している
っていう効率は良くないけどわかりやすい単純な方法
 
 
あとは選んだ色を並べて保存しておく機能がほしいなあ
 
 
 
 
WPFVB.NETでカラーピッカーその4、パレットを作って色を登録できるようにした ( ソフトウェア ) - 午後わてんのブログ - Yahoo!ブログ
http://blogs.yahoo.co.jp/gogowaten/14048893.html