午後わてんのブログ

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

WPF、Color(RGB)とHSVを相互変換するdll作ってみた、オブジェクトブラウザ使ってみた

 前回の

gogowaten.hatenablog.com

から

Color(RGB)とHSV(円柱モデル)を相互変換するdllを作ってみた
 
 
 
2018/03/03記事修正
修正箇所はこの色のところで
色相360を無彩色に割り当てていたのを通常の赤(360度=0度)に修正
 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Media;

namespace MyHSV
{
    /// <summary>
    /// Color(RGB)と円柱モデルHSVの相互変換、H=360は色相なし
    /// </summary>
    public class HSV
    {
        public double Hue;          //0.0fから360.0f
        public double Saturation;   //0.0fから1.0f
        public double Value;      //0.0fから1.0f

        /// <summary>
        /// 
        /// </summary>
        /// <param name="hue">0.0fから360.0f、360.0fは色相なし</param>
        /// <param name="saturation">0.0fから1.0f</param>
        /// <param name="value">0.0fから1.0f</param>
        public HSV(double hue = 0f, double saturation = 0f, double value = 0f)
        {
            Hue = hue;
            Saturation = saturation;
            Value = value;
        }

        /// <summary>
        /// Color(RGB)をHSV(円柱モデル)に変換、Hの値は0fから360f、SとVは0fから1f
        /// </summary>
        /// <param name="color"></param>
        /// <returns></returns>
        public static HSV Color2HSV(Color color)
        {
            byte R = color.R;
            byte G = color.G;
            byte B = color.B;
            byte Max = Math.Max(R, Math.Max(G, B));
            byte Min = Math.Min(R, Math.Min(G, B));
            if (Max == 0) {return new HSV(360f, 0f, 0f); }

            double chroma = Max - Min;
            double h = 0;
            double s = chroma / Max;
            double v = Max / 255f;

            if (Max == Min) { h = 360f; }
            else if (Max == R)
            {
                h = 60f * (G - B) / chroma;
                if (h < 0) { h += 360f; }
            }
            else if (Max == G)
            {
                h = 60f * (B - R) / chroma + 120f;
            }
            else if (Max == B)
            {
                h = 60f * (R - G) / chroma + 240f;
            }
            else { h = 360f; }

            return new HSV(h, s, v);
        }

        /// <summary>
        /// RGBをHSV(円柱モデル)に変換、RGBそれぞれの値を指定する
        /// </summary>
        /// <param name="r"></param>
        /// <param name="g"></param>
        /// <param name="b"></param>
        /// <returns></returns>
        public static HSV Color2HSV(byte r,byte g,byte b)
        {
            return Color2HSV(Color.FromRgb(r, g, b));
        }

        /// <summary>
        /// HSVをColorに変換
        /// </summary>
        /// <param name="hsv"></param>
        /// <returns></returns>
        public static Color HSV2Color(HSV hsv)
        {
            //double h = hsv.Hue / 60f, s = hsv.Saturation, v = hsv.Value;
            double h = (hsv.Hue % 360f) / 60f;
            double s = hsv.Saturation, v = hsv.Value;

            double r = v, g = v, b = v;

            if (v == 0) { return Color.FromRgb(0, 0, 0); }

            int i = (int)Math.Floor(h);
            double d = h - i;
            if (h < 1)
            {
                g *= 1f - s * (1f - d);
                b *= 1f - s;
            }
            else if (h < 2)
            {
                r *= 1f - s * d;
                b *= 1f - s;
            }
            else if (h < 3)
            {
                r *= 1f - s;
                b *= 1f - s * (1f - d);
            }
            else if (h < 4)
            {
                r *= 1f - s;
                g *= 1f - s * d;
            }
            else if (h < 5)
            {
                r *= 1f - s * (1f - d);
                g *= 1f - s;
            }
            else if (h < 6)
            {
                g *= 1f - s;
                b *= 1f - s * d;
            }


            return Color.FromRgb(
                (byte)Math.Round(r * 255f, MidpointRounding.AwayFromZero),
                (byte)Math.Round(g * 255f, MidpointRounding.AwayFromZero),
                (byte)Math.Round(b * 255f, MidpointRounding.AwayFromZero));
        }

        /// <summary>
        /// HSVをColorに変換、h,s,vそれぞれの値を指定する
        /// </summary>
        /// <param name="h">0fから360fの間で指定</param>
        /// <param name="s">0fから1fの間で指定</param>
        /// <param name="v">0fから1fの間で指定</param>
        /// <returns></returns>
        public static Color HSV2Color(double h,double s,double v)
        {
            return HSV2Color(new HSV(h, s, v));
        }
    }
}
 
 
 
HSVの値はH,S,Vともにdouble型
範囲は
H 0.0fから360.0fの間で360.0fが無彩色のつもり
S 0.0fから1.0fの間
V 0.0fから1.0fの間
 
HSVからColor(RGB)への変換はRGBそれぞれを最後に四捨五入してbyte型に変換してColorにしている
Color(RGB)からHSVへの変換で指定するColorは構造体のColorのほか、RGB各値をbyte型でも指定できる
public static HSV Color2HSV(byte r,byte g,byte b)
 
 
動作確認
イメージ 16
Color(RGB)からHSVへの変換確認
 
イメージ 17
HSVからColorへの変換確認
 
RGB→HSV→RGB
イメージ 18
RGB(159 ,124, 192) → HSV(270.882, 35.417, 75.294)
このHSVを四捨五入してRGBに戻してみたら
HSV(271, 35, 75) → RGB(159, 124, 191)
ズレが出ているのはHSVの指定で四捨五入しているから、だと思う
 
 
イメージ 19
HSV(79, 10, 8) → RGB(20,20, 18)
このRGBをHSVに変換すると
右 RGB(20,20, 18) → HSV(60, 10, 7.843)
色相がかなりずれる、これも四捨五入だからのはず、ColorのRGBはbyte型で小数点は使えないからこれはこれで正しいはず
Bが最低値でRとGが同じ値の時点で、色相は60の黄色に確定なんだよねえ
 
 
無彩色、色相なしの場合
イメージ 20
色相の値は360にしてみた
けど
イメージ 21
色相360度は0度にした(2018/03/03)
 
 
クラスライブラリのテンプレートから構造体Colorを使うにはPresentationCoreを参照に追加する必要がある

f:id:gogowaten:20191211171044p:plain

このクラスライブラリ(.NET Framework)ってのからdllを作るんだけど
 

f:id:gogowaten:20191211171058p:plain

クラスライブラリの初期画面
ここからColorを使おうとしても出てこない
 
 
イメージ 1
こんな感じでcolって入力しても入力候補にもColorが出てこない
 
イメージ 2
いつものWPFのアプリ作成のMainWindowなら
入力候補に出てくる
このクラスライブラリとWPFアプリの違いは参照の違いみたいで
クラスライブラリの参照にPresentationCoreっていうのを追加すればいいみたい
 
ソリューションエクスプローラーで比較してみる
イメージ 3
クラスライブラリは少ないねえ
 
参照にPresentationCoreを追加

f:id:gogowaten:20191211171123p:plain

ソリューションエクスプローラーで参照のところを右クリック→参照の追加で参照マネージャーを開く、ここまではこの前のDLLと同じ
アセンブリの項目を選んでおいてから、右上の検索枠でPresentationを入れると検索結果の中にPresentationCoreが見えるのでチェックを入れてok
これで参照にPresentationCoreが追加される
 
イメージ 5
PresentationCoreが追加されたところ
これでColorを使えるようになった
 
イメージ 6
入力候補に出てきた!
 
 
イメージ 7
毎回System.Windows.Mediaって入れるのはめんどくさいのでusing
これでいつものWPFアプリのように使えるようになった
 
 
Colorを探す?
イメージ 11
最初からColorを使えているMainWindowのほうでColorを入力して
Colorのところにカーソルを当てると説明が出る
System.Windows.Media
ってところに属しているみたいってのがわかる
 
イメージ 8
ソリューションエクスプローラーの参照の中の項目を右クリックすると
オブジェクトブラウザで表示ってのがある、選択すると
 
オブジェクトブラウザ

f:id:gogowaten:20191211171142p:plain

PresentationCoreが選択された状態、右下を見るとPresentationCore.dllってある
ってことはこれもdllなのかしら
それは置いといて、検索のところに"Color"を入れて検索すると
 
 

f:id:gogowaten:20191211171157p:plain

System.Windows.Media.Colorが見つかった
右下の概要ってところ見るとSystem.Windows.Mediaのメンバーってある
ここをクリックすると
 
 

f:id:gogowaten:20191211171204p:plain

PresentaionCoreのメンバー、またクリックすると
 
 

f:id:gogowaten:20191211171220p:plain

ここが一番上みたい、ってことでColorはPresentationCoreの中にあるってのがわかったことになる?
 
 

f:id:gogowaten:20191211171230p:plain

自分が作ったものの中も見れるんだなあ
 
 
イメージ 15
オブジェクトブラウザーを開くのはメニューからもできるのね
ショートカットキーはCtrl+Alt+J
 
 
 
参照したところ
Color Model:色をプログラムするブログ - Yahoo!ブログ
https://blogs.yahoo.co.jp/pspevolution7

明度と彩度の求め方 ( プログラム ) - Color Model:色をプログラムするブログ - Yahoo!ブログ
https://blogs.yahoo.co.jp/pspevolution7/17679694.html

colorstudy.livedoor.blog

https://blogs.yahoo.co.jp/pspevolution7/17682985.html
色相の求め方2 ( プログラム ) - Color Model:色をプログラムするブログ - Yahoo!ブログ
https://blogs.yahoo.co.jp/pspevolution7/17676223.html
PSPさんのブログには他にも色についての解説がたくさん
 
RGBをHSV(HSB)、HSL(HLS)、HSIに変換、復元する - .NET Tips (VB.NET,C#...)
https://dobon.net/vb/dotnet/graphics/hsv.html
小数点を切り捨て、切り上げ、四捨五入する - .NET Tips (VB.NET,C#...)
https://dobon.net/vb/dotnet/programing/round.html
 
 
カラーコード変換ツール | Hex、RGB、HSVCMYK、XYZ、LAB、HSLに対応
https://syncer.jp/color-converter
 
 
三角関数の基礎 SIN サイン 正弦 COS コサイン 余弦 TAN タンジェント 正接 ASIN ACOS アークコサイン COS-1 ATAN DEGREES RADIANS 度 角度 ラジアン 斜辺 対辺 隣辺 エクセル Excel [エクセルの学校]
http://www.excel.studio-kazu.jp/tips/0050/
 

関連記事
2018/03/12は22日後
色の距離は難しい、いくつか試したけどわからなかった ( ソフトウェア ) - 午後わてんのブログ - Yahoo!ブログ
https://blogs.yahoo.co.jp/gogowaten/15408771.html
HSV.DLLに円錐モデルを追加した
 
 
2018/2/18は2日前
dllファイル(クラスライブラリ.NET framework)の作り方と使うまでの手順メモ ( ソフトウェア ) - 午後わてんのブログ - Yahoo!ブログ
https://blogs.yahoo.co.jp/gogowaten/15377219.html
2018/3/1は10日後
HSVのグラデーションの画像を作成して保存するアプリ作ってみた ( ソフトウェア ) - 午後わてんのブログ - Yahoo!ブログ
https://blogs.yahoo.co.jp/gogowaten/15392811.html