加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
ColorSpace.cs 25.03 KB
一键复制 编辑 原始数据 按行查看 历史
Magician 提交于 2018-06-20 14:52 . 添加项目文件。
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.ComponentModel;
using System.ComponentModel.Design.Serialization;
using System.Globalization;
using System.Runtime.InteropServices;
using System.Reflection;
namespace ColorPane
{
/// <summary>
/// 提供色彩空间管理的类和相关的方法
/// </summary>
public class ColorSpace
{
/// <summary>
/// 设置一种颜色的亮度。
/// </summary>
public static Color SetBrightness(Color c, double brightness)
{
HSB hsl = RGB2HSB(c);
hsl.B = brightness;
return HSB2RGB(hsl);
}
/// <summary>
/// ControlPaint.Dark;ControlPaint.Light
/// </summary>
public static Color ModifyBrightness(Color c, double brightness)
{
HSB hsl = RGB2HSB(c);
hsl.B *= brightness;
return HSB2RGB(hsl);
}
/// <summary>
/// 设置颜色的饱和度。
/// </summary>
public static Color SetSaturation(Color c, double Saturation)
{
HSB hsl = RGB2HSB(c);
hsl.S = Saturation;
return HSB2RGB(hsl);
}
/// <summary>
/// 修改一个颜色的饱和度。
/// </summary>
public static Color ModifySaturation(Color c, double Saturation)
{
HSB hsl = RGB2HSB(c);
hsl.S *= Saturation;
return HSB2RGB(hsl);
}
/// <summary>
/// 设置颜色色调
/// </summary>
public static Color SetHue(Color c, double Hue)
{
HSB hsl = RGB2HSB(c);
hsl.H = Hue;
return HSB2RGB(hsl);
}
/// <summary>
///修改颜色色调
/// </summary>
public static Color ModifyHue(Color c, double Hue)
{
HSB hsl = RGB2HSB(c);
hsl.H *= Hue;
return HSB2RGB(hsl);
}
/// <summary>
/// HSB颜色空间到RGB颜色空间的转换
/// </summary>
public static Color HSB2RGB(HSB hsb)
{
int Alpha = (int)Math.Round(hsb.A * 255);
double r = 0;
double g = 0;
double b = 0;
double hue = hsb.H * 360;
if (hsb.S == 0)
{
r = g = b = hsb.B;
}
else
{
// the color wheel consists of 6 sectors. Figure out which sector you're in.
double sectorPos = hue / 60.0;
int sectorNumber = (int)(Math.Floor(sectorPos));
// get the fractional part of the sector
double fractionalSector = sectorPos - sectorNumber;
// calculate values for the three axes of the color.
double p = hsb.B * (1.0 - hsb.S);
double q = hsb.B * (1.0 - (hsb.S * fractionalSector));
double t = hsb.B * (1.0 - (hsb.S * (1 - fractionalSector)));
// assign the fractional colors to r, g, and b based on the sector the angle is in.
switch (sectorNumber)
{
case 0:
r = hsb.B;
g = t;
b = p;
break;
case 1:
r = q;
g = hsb.B;
b = p;
break;
case 2:
r = p;
g = hsb.B;
b = t;
break;
case 3:
r = p;
g = q;
b = hsb.B;
break;
case 4:
r = t;
g = p;
b = hsb.B;
break;
case 5:
r = hsb.B;
g = p;
b = q;
break;
}
}
return Color.FromArgb(Alpha, (int)Math.Round(r * 255), (int)Math.Round(g * 255), (int)Math.Round(b * 255));
}
/// <summary>
/// 将RGB颜色空间的颜色转换到HSB颜色空间对应的值
/// </summary>
/// <param name="c">RGB颜色</param>
/// <returns>HSB颜色</returns>
public static HSB RGB2HSB(Color c)
{
double r = ((double)c.R / 255.0);
double g = ((double)c.G / 255.0);
double b = ((double)c.B / 255.0);
double max = Math.Max(r, Math.Max(g, b));
double min = Math.Min(r, Math.Min(g, b));
double h = 0.0;
if (max == r && g >= b)
{
if (max - min == 0) h = 0.0;
else h = 60 * (g - b) / (max - min);
}
else if (max == r && g < b)
{
h = 60 * (g - b) / (max - min) + 360;
}
else if (max == g)
{
h = 60 * (b - r) / (max - min) + 120;
}
else if (max == b)
{
h = 60 * (r - g) / (max - min) + 240;
}
double s = (max == 0) ? 0.0 : (1.0 - ((double)min / (double)max));
return new HSB(c.A / 255.0f, h / 360, s, (double)max);
}
/// <summary>
/// RGB颜色空间到CMYK颜色空间的转换
/// </summary>
/// <param name="c">RGB颜色</param>
/// <returns>CMYK颜色</returns>
public static CMYK RGB2CMYK(Color c)
{
CMYK _cmyk = new CMYK();
double R, G, B;
R = (double)c.R;
G = (double)c.G;
B = (double)c.B;
R = 1.0 - (R / 255.0);
G = 1.0 - (G / 255.0);
B = 1.0 - (B / 255.0);
double C, M, Y, K;
if (R < G)
K = R;
else
K = G;
if (B < K)
K = B;
if (K == 1.0) C = M = Y = 0;
else
{
C = (R - K) / (1.0 - K);
M = (G - K) / (1.0 - K);
Y = (B - K) / (1.0 - K);
}
//修正CMYK值
C = (C * 100) + 0.5;
M = (M * 100) + 0.5;
Y = (Y * 100) + 0.5;
K = (K * 100) + 0.5;
_cmyk.C = C / 100.0;
_cmyk.M = M / 100.0;
_cmyk.Y = Y / 100.0;
_cmyk.K = K / 100.0;
return _cmyk;
}
/// <summary>
/// 将颜色从RGB空间转换为2°观察者模式,D65明度LAB空间。
/// </summary>
/// <param name="c"></param>
/// <returns></returns>
public static LAB RGB2LAB(Color c)
{
LAB lab = new LAB();
double X, Y, Z, fX, fY, fZ;
X = 0.412453 * c.R + 0.357580 * c.G + 0.180423 * c.B;
Y = 0.212671 * c.R + 0.715160 * c.G + 0.072169 * c.B;
Z = 0.019334 * c.R + 0.119193 * c.G + 0.950227 * c.B;
X /= (255 * 0.950456);
Y /= 255;
Z /= (255 * 1.088754);
if (Y > 0.008856)
{
fY = Math.Pow(Y, 1.0 / 3.0);
lab.L = 116.0 * fY - 16.0;
}
else
{
fY = 7.787 * Y + 16.0 / 116.0;
lab.L = 903.3 * Y;
}
if (X > 0.008856)
fX = Math.Pow(X, 1.0 / 3.0);
else
fX = 7.787 * X + 16.0 / 116.0;
if (Z > 0.008856)
fZ = Math.Pow(Z, 1.0 / 3.0);
else
fZ = 7.787 * Z + 16.0 / 116.0;
lab.A = 500.0 * (fX - fY);
lab.B = 200.0 * (fY - fZ);
lab.Alpha = (c.A - 128);
return lab;
}
/// <summary>
/// 将颜色从2°观察者模式,D65明度LAB空间转换为RGB颜色空间。
/// </summary>
public static Color LAB2RGB(LAB lab)
{
int alpha = (int)(lab.Alpha + 128);
double X, Y, Z, fX, fY, fZ;
double RR, GG, BB, R, G, B;
fY = Math.Pow((lab.L + 16.0) / 116.0, 3.0);
if (fY < 0.008856)
fY = lab.L / 903.3;
Y = fY;
if (fY > 0.008856)
fY = Math.Pow(fY, 1.0 / 3.0);
else
fY = 7.787 * fY + 16.0 / 116.0;
fX = lab.A / 500.0 + fY;
if (fX > 0.206893)
X = Math.Pow(fX, 3.0);
else
X = (fX - 16.0 / 116.0) / 7.787;
fZ = fY - lab.B / 200.0;
if (fZ > 0.206893)
Z = Math.Pow(fZ, 3.0);
else
Z = (fZ - 16.0 / 116.0) / 7.787;
X *= (0.950456 * 255);
Y *= 255;
Z *= (1.088754 * 255);
RR = 3.240479 * X - 1.537150 * Y - 0.498535 * Z;
GG = -0.969256 * X + 1.875992 * Y + 0.041556 * Z;
BB = 0.055648 * X - 0.204043 * Y + 1.057311 * Z;
R = (float)(RR < 0 ? 0 : RR > 255 ? 255 : RR);
G = (float)(GG < 0 ? 0 : GG > 255 ? 255 : GG);
B = (float)(BB < 0 ? 0 : BB > 255 ? 255 : BB);
return Color.FromArgb(alpha, (int)Math.Round(R), (int)Math.Round(G), (int)Math.Round(B));
}
/// <summary>
/// CMYK颜色空间到RGB颜色空间的转换
/// </summary>
/// <param name="_cmyk">CMYK颜色</param>
/// <returns>RGB颜色</returns>
public static Color CMYK2RGB(CMYK cmyk)
{
byte r, g, b;
double R, G, B;
double C, M, Y, K;
C = (double)cmyk.C;
M = (double)cmyk.M;
Y = (double)cmyk.Y;
K = (double)cmyk.K;
R = C * (1.0 - K) + K;
G = M * (1.0 - K) + K;
B = Y * (1.0 - K) + K;
//修正RGB值
R = (1.0 - R) * 255.0 + 0.5;
G = (1.0 - G) * 255.0 + 0.5;
B = (1.0 - B) * 255.0 + 0.5;
r = (byte)R;
g = (byte)G;
b = (byte)B;
return Color.FromArgb(r, g, b);
}
/// <summary>
/// 将指定颜色转换为网页安全的颜色。
/// </summary>
public static Color ToWebSafeColor(Color value)
{
int A, R, G, B;
A = 255;
R = (int)Math.Round((float)value.R / 51.0f) * 51;
G = (int)Math.Round((float)value.G / 51.0f) * 51;
B = (int)Math.Round((float)value.B / 51.0f) * 51;
return Color.FromArgb(A, R, G, B);
}
/// <summary>
/// 测试指定的颜色值是否是网页安全的颜色。
/// </summary>
public static bool IsWebSafeColor(Color value)
{
if (value.A != 255) return false;
if ((value.R % 51) != 0) return false;
if ((value.G % 51) != 0) return false;
if ((value.B % 51) != 0) return false;
return true;
}
/// <summary>
/// 测试指定的颜色是否是打印机安全的颜色。
/// </summary>
/// <param name="cmyk"></param>
/// <returns></returns>
public static bool IsPrinterSafeColor(CMYK cmyk)
{
if ((cmyk.C - (int)Math.Round(cmyk.C, 2)) != 0) return false;
if ((cmyk.M - (int)Math.Round(cmyk.M, 2)) != 0) return false;
if ((cmyk.Y - (int)Math.Round(cmyk.Y, 2)) != 0) return false;
if ((cmyk.K - (int)Math.Round(cmyk.K, 2)) != 0) return false;
return true;
}
/// <summary>
/// 将指定颜色转换为打印机安全的颜色。
/// </summary>
/// <param name="cmyk"></param>
/// <returns></returns>
public static Color ToPrinterSafeColor(CMYK cmyk)
{
return CMYK2RGB(new CMYK((int)Math.Round(cmyk.C, 2), (int)Math.Round(cmyk.M, 2), (int)Math.Round(cmyk.Y, 2), (int)Math.Round(cmyk.K, 2)));
}
/// <summary>
/// Custom rounding function.
/// </summary>
/// <param name="val">Value to round</param>
/// <returns>Rounded value</returns>
private static int Round(double val)
{
int ret_val = (int)val;
int temp = (int)(val * 100);
if ((temp % 100) >= 50)
ret_val += 1;
return ret_val;
}
#region Public Classes
[Serializable(), TypeConverter(typeof(ExpandableObjectConverter))]// TypeConverter(typeof(HSBConvertor))]
public struct HSB
{
#region Class Variables
public static HSB Empty;
private double _h;
private double _s;
private double _b;
private double _a;//Alpha
#endregion
public HSB(double a, double h, double s, double b)
{
_a = a > 1 ? 1 : a < 0 ? 0 : a;
_h = h > 1 ? 1 : h < 0 ? 0 : h;
_s = s > 1 ? 1 : s < 0 ? 0 : s;
_b = b > 1 ? 1 : b < 0 ? 0 : b;
}
public HSB(double h, double s, double b )
: this(1.0d, h , s, b)
{
}
//public HSB()
// : this(1.0d, 0, 0, 0)
//{
//}
#region Public Methods
public double A
{
get { return _a; }
set
{
_a = value;
_a = _a > 1 ? 1 : _a < 0 ? 0 : _a;
}
}
public double H
{
get { return _h; }
set
{
_h = value;
_h = _h > 1 ? 1 : _h < 0 ? 0 : _h;
}
}
public double S
{
get { return _s; }
set
{
_s = value;
_s = _s > 1 ? 1 : _s < 0 ? 0 : _s;
}
}
public double B
{
get { return _b; }
set
{
_b = value;
_b = _b > 1 ? 1 : _b < 0 ? 0 : _b;
}
}
public override int GetHashCode()
{
return base.GetHashCode();
}
public override bool Equals(object obj)
{
return base.Equals(obj);
}
public Color ToRGB()
{
return ColorSpace.HSB2RGB(this);
}
public CMYK ToCMYK()
{
return ColorSpace.RGB2CMYK(ToRGB());
}
public static bool operator ==(HSB left, HSB right)
{
return left._a == right._a && left._b == right._b && left._h == right._h && left._s == right._s;
}
public static bool operator !=(HSB left, HSB right)
{
return !(left == right);
}
public static implicit operator Color(HSB value)
{
return value.ToRGB();
}
public static HSB FromHSB(double h, double s, double b)
{
return FromHSB(1.0d, h, s, b);
}
public static HSB FromHSB(double a, double h, double s, double b)
{
HSB value = new HSB();
value.A = a;
value.H = h;
value.S = s;
value.B = b;
return value;
}
public static HSB FromRGB(Color c)
{
return ColorSpace.RGB2HSB(c);
}
public static HSB FromCMYK(CMYK cmyk)
{
Color c = ColorSpace.CMYK2RGB(cmyk);
return ColorSpace.RGB2HSB(c);
}
#endregion
}
public class HSBConvertor : ExpandableObjectConverter
{
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
if (sourceType == typeof(string))
{
return true;
}
return base.CanConvertFrom(context, sourceType);
}
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
{
if (destinationType == typeof(InstanceDescriptor))
{
return true;
}
return base.CanConvertTo(context, destinationType);
}
public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
{
if (value is string)
{
string s = (string)value;
string[] text = s.Split(culture.TextInfo.ListSeparator.ToCharArray());
return HSB.FromHSB(double.Parse(text[0]), double.Parse(text[1]), double.Parse(text[2]), double.Parse(text[3]));
}
return base.ConvertFrom(context, culture, value);
}
public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType)
{
if (destinationType == null)
{
throw new ArgumentNullException("destinationType");
}
if (value.ToString().Equals(typeof(HSB).FullName))
{
if (destinationType == typeof(string))
{
string[] rettext;
HSB hsb = (HSB)value;
if (hsb == HSB.Empty)
{
return string.Empty;
}
if (culture == null)
{
culture = CultureInfo.CurrentCulture;
}
string text1 = culture.TextInfo.ListSeparator + " ";
TypeConverter converter1 = TypeDescriptor.GetConverter(typeof(double));
int num1 = 0;
rettext = new string[4];
rettext[num1++] = converter1.ConvertToString(context, culture, hsb.A);
rettext[num1++] = converter1.ConvertToString(context, culture, hsb.H);
rettext[num1++] = converter1.ConvertToString(context, culture, hsb.S);
rettext[num1++] = converter1.ConvertToString(context, culture, hsb.B);
return string.Join(text1, rettext);
}
if (destinationType == typeof(InstanceDescriptor))
{
MemberInfo info = null;
ConstructorInfo ci = null;
object[] objArray1 = null;
HSB hsb = (HSB)value;
if (hsb == HSB.Empty)
{
info = typeof(HSB).GetField("Empty");
}
else
{
info = typeof(HSB).GetMethod("FromHSB", new Type[] { typeof(double), typeof(double), typeof(double), typeof(double) });
ci = typeof(HSB).GetConstructor(new Type[] { typeof(double), typeof(double), typeof(double), typeof(double) });
objArray1 = new object[] { hsb.A, hsb.H, hsb.S, hsb.B };
}
if (info != null)
{
//return new InstanceDescriptor(ci, objArray1);
return new InstanceDescriptor(info, objArray1);
}
return null;
}
}
return null;// return base.ConvertTo(context, culture, value, destinationType);
}
}
[Serializable()]
public struct CMYK
{
#region Class Variables
double _c;
double _m;
double _y;
double _k;
#endregion
public CMYK(double c, double m, double y, double k)
{
_c = c;
_m = m;
_y = y;
_k = k;
_c = _c > 1 ? 1 : _c < 0 ? 0 : _c;
_m = _m > 1 ? 1 : _m < 0 ? 0 : _m;
_y = _y > 1 ? 1 : _y < 0 ? 0 : _y;
_k = _k > 1 ? 1 : _k < 0 ? 0 : _k;
}
public double C
{
get { return _c; }
set
{
_c = value;
_c = _c > 1 ? 1 : _c < 0 ? 0 : _c;
}
}
public double M
{
get { return _m; }
set
{
_m = value;
_m = _m > 1 ? 1 : _m < 0 ? 0 : _m;
}
}
public double Y
{
get { return _y; }
set
{
_y = value;
_y = _y > 1 ? 1 : _y < 0 ? 0 : _y;
}
}
public double K
{
get { return _k; }
set
{
_k = value;
_k = _k > 1 ? 1 : _k < 0 ? 0 : _k;
}
}
#region Public Methods
public static CMYK FromCMYK(double c, double m, double y, double k)
{
return new CMYK(c, m, y, k);
}
public Color ToRGB()
{
return ColorSpace.CMYK2RGB(this);
}
public Color ToPrinterSafeColor()
{
return ColorSpace.ToPrinterSafeColor(this);
}
#endregion
}
[Serializable()]
public struct LAB
{
public static LAB Empty;
private double _alpha;//Alpha通道
private double _l;
private double _a;
private double _b;
public LAB(double alpha, double l, double a, double b)
{
_alpha = alpha;
_l = l;
_a = a;
_b = b;
_alpha = _alpha > 127 ? 127 : _alpha < -128 ? -128 : _alpha;
_l = _l > 127 ? 127 : _l < -128 ? -128 : _l;
_a = _a > 127 ? 127 : _a < -128 ? -128 : _a;
_b = _b > 127 ? 127 : _b < -128 ? -128 : _b;
}
public LAB(double l, double a, double b )
: this(127.0d, l , a, b)
{
}
public static LAB FromRGB(Color rgb)
{
return ColorSpace.RGB2LAB(rgb);
}
public static LAB FromLAB(double alpha, double l, double a , double b)
{
return new LAB(alpha, l, a, b);
}
public static LAB FromLAB(double l, double a, double b)
{
return new LAB(l, a, b);
}
public Color ToRGB()
{
return ColorSpace.LAB2RGB(this);
}
public static bool operator ==(LAB left, LAB right)
{
return left._a == right._a && left._alpha == right._alpha && left._b == right._b && left._l == right._l;
}
public static bool operator !=(LAB left, LAB right)
{
return !(left == right);
}
public static implicit operator Color(LAB value)
{
return value.ToRGB();
}
public override bool Equals(object obj)
{
return base.Equals(obj);
}
public override int GetHashCode()
{
return base.GetHashCode();
}
#region 公用属性
public double Alpha
{
get { return _alpha; }
set
{
_alpha = value;
_alpha = _alpha > 127 ? 127 : _alpha < -128 ? -128 : _alpha;
}
}
public double L
{
get { return _l; }
set
{
_l = value;
_l = _l > 127 ? 127 : _l < -128 ? -128 : _l;
}
}
public double A
{
get { return _a; }
set
{
_a = value;
_a = _a > 127 ? 127 : _a < -128 ? -128 : _a;
}
}
public double B
{
get { return _b; }
set
{
_b = value;
_b = _b > 127 ? 127 : _b < -128 ? -128 : _b;
}
}
#endregion
}
#endregion
}
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化