Ktouth Brand. on Web

け〜くんこと K.Ktouth のだらだらした日常と突発的に作るプログラムや読み物とかの雑多サイト



[2010年01月31日]

RGB <=> HSB 変換で

2010年02月01日 07:45更新 筆者:K.Ktouth

指定した色(RGB)から明るめの色、暗めの色を自動生成しようとして、RGB→HSB→RGBという変換処理を作ろうとしたのだけど、困ったことにWPF、というか.netの標準機能にはHSBを基準とした色機能は実装されていないっぽい。
なら自前で作るかー、と軽い気持ちで始めたら、それだけで2時間悩みっぱなし(ぉぃ

ググったところ、まずここが引っかかったんで、これを参考にコードを書けばいいかなぁ……と思ったら。なんと言っていることが全く理解できないげー
いや、文章部分はわかるんだけど、いざ数式が書かれると、どういう風になってこういう式になったのかがうまく繋がらないという感じ。

いかん、どうしよう。10年以上高等数学とか復習してないから、さっぱりついて行けねーぞあせ

焦りながら別のページも検索。まんまソースコードが載っているページもあったけど、まんま流用は後々困るかも知れないので除外するとして……すると Wikipedia に端的に表現された数式が。

後半にかなりシンプルな表現で書かれていてわかりやすかった(ぉ
これを C#/WPF で記述するとこんな感じ……

public struct HSB
{
  public ushort H;
  public byte S;
  public byte B;

  public HSB(System.Window.Media.Color c)
  {
    var max = Math.Max(Math.Max(c.R, c.G), c.B);
    var min = Math.Min(Math.Min(c.R, c.G), c.B);
    double range = max - min;

    if (range == 0) { H = 0; S = 0; }
    else
    {
      double h = 0.0;
      if (max == c.R) { h = 60.0 * ((c.G - c.B) / range) + 0.0; } // h => 300 .. 0 .. 60
      else if (max == c.G) { h = 60.0 * ((c.B - c.R) / range) + 120.0; } // h => 60 .. 120 .. 180
      else { h = 60.0 * ((c.R - c.G) / range) + 240.0; } // h => 180 .. 240 .. 300
      while(h < 0) { h += 360.0; }
      H = (ushort)Math.Round(h % 360);

      S = (byte)Math.Round(range * byte.MaxValue / max);
    }
    B = max;
  }
}

HSB→RGBのコードは省略。
とりあえずわかったことは。今から情報処理国家資格の再取得は絶望的だって事あせ
英語はもちろん、得意だったはずの理数系ですからこの有様じゃなぁ……

本日のリンク元
アンテナ
その他のリンク元
検索