C#でHSBで色指定してラスタ画像を描いてみた

C#でピクセルに色指定するさいに使うColor構造体はARGBで色指定するのですが、HSB方式でも色指定したくてやってみたメモです。 試した環境は下記です。

  • Visual Studio 2015 Express for Windows Desktop

目次

  1. HSB色空間とは
  2. 試してみた
    1. 彩度を固定したスペクトル図
    2. 明度を固定したスペクトル

HSB色空間とは

赤(Red)緑(Green)青(Blue)の3原色で色を表す方法ではなく、色相(Hue)彩度(Saturation)明度(Brightness)で色を表す方法です。配色を考えるときにHSBで考えた方が便利なのです。詳しくはWikipediaなどを参照してください。 System.Drawing.Color構造体には、RGBからColorオブジェクトを作るメソッドはありますが、HSBを指定できるメソッドはありません。ということで、Wikipediaの計算式を参考にしてHSBをRGBに変換して絵を描いてみます。

試してみた

彩度を固定したスペクトル図

360x100のPNG画像を描きます。x=0を色相0度としてx方向に色相を360度分だけ変化させます。また、y方向には、明度を最大から最小まで変化させます。 コードは下記です。Wikipadiaにサンプルコードがありましたが、コードの方は参考にはしませんでした。(ライセンスの扱いがよくわからなかったので。)コードを記述する前に、System.Drawingへの参照を追加しないとIntelli Senseさんに怒られます。

using System;
using System.Windows;
using System.Drawing;
using System.Drawing.Imaging;

namespace image_trial2
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            int width = 360;
            int height = 100;
            Bitmap bitmap = new Bitmap(width, height);

            double saturation = 0.999999999999999;
            for (int x = 0; x < width; x++)
            {
                double hue = ((double)x / width) * 360;
                for (int y = 0; y < height; y++)
                {
                    double brightness = (double)(height - 1 - y) / height;
                    System.Drawing.Color color = ColorFromHSB(hue, saturation, brightness);
                    bitmap.SetPixel(x, y, color);
                }
            }
            string filename = @"ファイル名";
            bitmap.Save(filename,ImageFormat.Png);
        }

        private System.Drawing.Color ColorFromHSB(double hue, double saturation, double brightness)
        {
            if (saturation == 0)
            {
                return System.Drawing.Color.FromArgb(255, (int)Math.Floor(brightness * 256), (int)Math.Floor(brightness * 256), (int)Math.Floor(brightness * 256));
            }

            double valueC = brightness * saturation;
            double valueHdash = hue / 60;
            double valueX = valueC * (1 - Math.Abs(valueHdash % 2 - 1));

            double red = 0;
            double green = 0;
            double blue = 0;

            int valueHdashForSwitch = (int)Math.Floor(valueHdash);
            switch (valueHdashForSwitch)
            {
                case 0:
                    red = brightness;
                    green = brightness - valueC + valueX;
                    blue = brightness - valueC;
                    break;
                case 1:
                    red = brightness - valueC + valueX;
                    green = brightness;
                    blue = brightness - valueC;
                    break;
                case 2:
                    red = brightness - valueC;
                    green = brightness;
                    blue = brightness - valueC + valueX;
                    break;
                case 3:
                    red = brightness - valueC;
                    green = brightness - valueC + valueX;
                    blue = brightness;
                    break;
                case 4:
                    red = brightness - valueC + valueX;
                    green = brightness - valueC;
                    blue = brightness;
                    break;
                case 5:
                    red = brightness;
                    green = brightness - valueC;
                    blue = brightness - valueC + valueX;
                    break;
            }
            System.Drawing.Color color = System.Drawing.Color.FromArgb(255, (int)Math.Floor(red * 256), (int)Math.Floor(green * 256), (int)Math.Floor(blue * 256));
            return color;
        }
    }
}

HSBを入れたらRGBのColorオブジェクトを返すメソッドを作って、それを描画ルーチンから呼び出すようにしました。変数saturationに1未満の最大値を指定したかったのですが、どうすればよいのかよく分りませんでした。きっと計算機科学をやってる人なら簡単なのでしょうね。 実行すると、下図の画像ファイルが得られます。 160217-2-01

明度を固定したスペクトル

前述と同様に、今度は明度を固定してスペクトルを描いてみます。

using System;
using System.Windows;
using System.Drawing;
using System.Drawing.Imaging;

namespace image_trial2
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            int width = 360;
            int height = 100;
            Bitmap bitmap = new Bitmap(width, height);

            double brightness = 0.999999999999999;
            for (int x = 0; x < width; x++)
            {
                double hue = ((double)x / width) * 360;
                for (int y = 0; y < height; y++)
                {
                    double saturation = (double)(height - 1 - y) / height;
                    System.Drawing.Color color = ColorFromHSB(hue, saturation, brightness);
                    bitmap.SetPixel(x, y, color);
                }
            }
            string filename = @"ファイル名";
            bitmap.Save(filename,ImageFormat.Png);
        }
    }
}

ColorFromHSB()メソッドの中身は前述と全く同じです。 実行すると下図の画像ファイルが得られます。 160217-2-02

公開日

広告