/// <summary> /// 色のブレンディング処理を行う。 /// 通常のブレンドモード(Nrmal, c1) /// /// ブレンディング処理については以下のURLを参考にした。 /// http://d.hatena.ne.jp/yus_iri/20110921/1316610121 /// </summary> /// <param name="c1">色1(前景色)</param> /// <param name="c2">色2(背景色)</param> /// <returns>ブレンディングされた色</returns> public static Color Blend(Color c1, Color c2) { if ((c1.A >= 255) || (c2.A == 0)) { // c1.Aが255(不透明)または c2.Aが透過(A=0)だと、 // 計算結果がc1になるのでそのまま返す。 return(c1); } float a1 = (c1.A * c2.A) / (float)(255 * 255); float a2 = (c1.A * (255 - c2.A)) / (float)(255 * 255); float a3 = ((255 - c1.A) * c2.A) / (float)(255 * 255); float alpha = a1 + a2 + a3; if (alpha == 0) { return(Color.FromArgb(0, 0, 0, 0)); } // Note: ブレンドモードがNormalじゃないなら、a1に乗算する対象を変える必要がある。 int r = (int)(ColorUtility.Clamp((a1 * c1.R + a2 * c1.R + a3 * c2.R) / alpha, 0, 255)); int g = (int)(ColorUtility.Clamp((a1 * c1.G + a2 * c1.G + a3 * c2.G) / alpha, 0, 255)); int b = (int)(ColorUtility.Clamp((a1 * c1.B + a2 * c1.B + a3 * c2.B) / alpha, 0, 255)); int a = (int)(ColorUtility.Clamp(alpha * 255, 0, 255)); return(Color.FromArgb(a, r, g, b)); }
/// <summary> /// cで指定された色で着色して返す。 /// </summary> /// <remarks>このアルゴリズムでいいんだろうか</remarks> /// <param name="srcColor"></param> /// <param name="c"></param> /// <returns>着色した色</returns> public static Color ProcessColoring(Color srcColor, Color c) { // Note: BT.709でグレースケール変換する。 float v = 0.2126f * srcColor.R / 255.0f + 0.7152f * srcColor.G / 255.0f + 0.0722f * srcColor.B / 255.0f; if (v < 0.5) { // 暗い方は割合として使用する。 float rate = v * 2; int r = ColorUtility.Clamp(Convert.ToInt32(c.R * rate), 0, 255); int g = ColorUtility.Clamp(Convert.ToInt32(c.G * rate), 0, 255); int b = ColorUtility.Clamp(Convert.ToInt32(c.B * rate), 0, 255); return(Color.FromArgb(srcColor.A, r, g, b)); } else { // 明るい方は、白に寄せる。 float rate = (v - 0.5f) * 2; int r = ColorUtility.Clamp(Convert.ToInt32(c.R + (255 - c.R) * rate), 0, 255); int g = ColorUtility.Clamp(Convert.ToInt32(c.G + (255 - c.R) * rate), 0, 255); int b = ColorUtility.Clamp(Convert.ToInt32(c.B + (255 - c.R) * rate), 0, 255); return(Color.FromArgb(srcColor.A, r, g, b)); } }
/// <summary> /// 新しいHSL色を得る。 /// </summary> /// <param name="alpha">不透明度(0.0≦alpha≦1.0)</param> /// <param name="hue">色相(0.0≦hue<360)</param> /// <param name="saturation">彩度(0.0≦saturation≦1.0)</param> /// <param name="lightness">輝度(0.0≦lightness≦1.0)</param> /// <returns>色</returns> public static ColorHSL FromAHSL(float alpha, float hue, float saturation, float lightness) { float a = ColorUtility.Clamp(alpha, 0.0f, 1.0f); float h = ColorUtility.GetHueWithLimitedRange(hue); float s = ColorUtility.Clamp(saturation, 0.0f, 1.0f); float l = ColorUtility.Clamp(lightness, 0.0f, 1.0f); return(new ColorHSL(a, h, s, l)); }
/// <summary> /// セピア色に変換する /// </summary> /// <param name="color">色</param> /// <returns>セピア調の色</returns> /// <remarks> /// 下記サイトを参考にした。 /// http://k-ichikawa.blog.enjoy.jp/etc/HP/htm/imageSepia.html /// </remarks> public static Color SepiaColor(Color color) { float v = 0.2126f * color.R / 255.0f + 0.7152f * color.G / 255.0f + 0.0722f * color.B / 255.0f; int r = ColorUtility.Clamp(Convert.ToInt32(v * 255.0f), 0, 255); int g = ColorUtility.Clamp(Convert.ToInt32(v * 74.0f / 107.0f * 255.0f), 0, 255); int b = ColorUtility.Clamp(Convert.ToInt32(v * 43.0f / 107.0f * 255.0f), 0, 255); return(Color.FromArgb(color.A, r, g, b)); }
/// <summary> /// HSVからRGBへ変換を行う /// </summary> /// <param name="hsv">HSVカラー</param> /// <param name="alpha">アルファ値(0≦alpha≦1.0)</param> /// <returns>RGBカラーが返る</returns> public static Color ConvertHSVtoRGB(ColorHSV hsv, float alpha) { int a = ColorUtility.Clamp(Convert.ToInt32(alpha * 255.0f), 0, 255); return(ConvertHSVtoRGB(hsv, (byte)(a))); }
/// <summary> /// HSLからRGBへ変換を行う。 /// </summary> /// <param name="hsl">HSL色</param> /// <param name="alpha">アルファ値(0≦alpha≦1.0)</param> /// <returns>RGB色</returns> public static Color ConvertHSLtoRGB(ColorHSL hsl, float alpha) { int a = Convert.ToInt32(ColorUtility.Clamp(alpha * 255.0f, 0.0f, 255.0f)); return(ConvertHSLtoRGB(hsl, (byte)(a))); }