using System; using System.ComponentModel; using System.Drawing; using System.Runtime.InteropServices; using System.Text; namespace Microsoft.Drawing { /// /// 颜色向量,只支持加减操作,不支持乘除操作 /// Copyright (c) JajaSoft /// [Serializable, StructLayout(LayoutKind.Sequential), ComVisible(true), TypeConverter(typeof(ColorVectorConverter))] public struct ColorVector { #region 静态 /// /// A=0,R=0,G=0,B=0 /// public static readonly ColorVector Empty; /// /// 静态构造 /// static ColorVector() { Empty = new ColorVector(); } /// /// 生成Long,各占16位共64位 /// /// A /// R /// G /// B /// 长整型数值 private static long MakeLong(int alpha, int red, int green, int blue) { ulong ulA = (ulong)(alpha & ushort.MaxValue); ulong ulR = (ulong)(red & ushort.MaxValue); ulong ulG = (ulong)(green & ushort.MaxValue); ulong ulB = (ulong)(blue & ushort.MaxValue); return (long)((ulA << 0x30) | (ulR << 0x20) | (ulG << 0x10) | ulB); } /// /// 从一个64位整数创建ColorVector结构 /// /// 64位整数 /// ColorVector结构 public static ColorVector FromArgb(long value) { return new ColorVector(value); } /// /// 从一个Color结构创建ColorVector结构 /// /// Color结构 /// ColorVector结构 public static ColorVector FromArgb(Color color) { return new ColorVector(color.A, color.R, color.G, color.B); } /// /// 从一个Color结构创建ColorVector结构,但Alpha使用指定的值 /// /// Alpha指定值 /// Color结构 /// ColorVector结构 public static ColorVector FromArgb(int alpha, Color color) { return new ColorVector(alpha, color.R, color.G, color.B); } /// /// 从一个ColorVector结构创建ColorVector结构,但Alpha使用指定值 /// /// Alpha指定值 /// ColorVector结构 /// ColorVector结构 public static ColorVector FromArgb(int alpha, ColorVector vector) { return new ColorVector(alpha, vector.R, vector.G, vector.B); } /// /// 从三个16位整数创建ColorVector结构,Alpha使用0 /// /// Red值 /// Green值 /// Blue值 /// ColorVector结构 public static ColorVector FromArgb(int red, int green, int blue) { return new ColorVector(0, red, green, blue); } /// /// 从四个16位整数创建ColorVector结构 /// /// Alpha值 /// Red值 /// Green值 /// Blue值 /// ColorVector结构 public static ColorVector FromArgb(int alpha, int red, int green, int blue) { return new ColorVector(alpha, red, green, blue); } #endregion #region 字段属性 //64位值 private long Value; /// /// Alpha分量上的偏移量 /// public short A { get { return (short)((this.Value >> 0x30) & ushort.MaxValue); } } /// /// 红色分量上的偏移量 /// public short R { get { return (short)((this.Value >> 0x20) & ushort.MaxValue); } } /// /// 绿色分量上的偏移量 /// public short G { get { return (short)((this.Value >> 0x10) & ushort.MaxValue); } } /// /// 蓝色分量上的偏移量 /// public short B { get { return (short)(this.Value & ushort.MaxValue); } } #endregion #region 构造函数 /// /// 构造函数 /// /// 长整型数值 private ColorVector(long value) { this.Value = value; } /// /// 构造函数,各占16位.short(-32768,32767) /// /// A /// R /// G /// B private ColorVector(int alpha, int red, int green, int blue) : this(MakeLong(alpha, red, green, blue)) { } #endregion #region 公共方法 /// /// 获取Hash值 /// /// 返回 public override int GetHashCode() { return this.Value.GetHashCode(); } /// /// 转换为字符串 /// /// 字符串 public override string ToString() { StringBuilder builder = new StringBuilder(0x20); builder.Append(base.GetType().Name); builder.Append(" ["); if (this == ColorVector.Empty) { builder.Append("Empty"); } else { builder.Append("A="); builder.Append(this.A); builder.Append(", R="); builder.Append(this.R); builder.Append(", G="); builder.Append(this.G); builder.Append(", B="); builder.Append(this.B); } builder.Append("]"); return builder.ToString(); } /// /// 判断两个是否相等 /// /// 目标对象 /// 相等返回true,否则返回false public override bool Equals(object obj) { if (obj is ColorVector) { ColorVector vector = (ColorVector)obj; return this == vector; } return false; } /// /// 转换为颜色 /// /// 颜色 public Color ToColor() { return Color.FromArgb(MathEx.Clamp(this.A, (byte)0, (byte)255), MathEx.Clamp(this.R, (byte)0, (byte)255), MathEx.Clamp(this.G, (byte)0, (byte)255), MathEx.Clamp(this.B, (byte)0, (byte)255)); } #endregion #region 操作符 /// /// 等于 /// /// 左值 /// 右值 /// 相等返回true,否则返回false public static bool operator ==(ColorVector left, ColorVector right) { return left.Value == right.Value; } /// /// 等于 /// /// 左值 /// 右值 /// 不等返回true,否则返回false public static bool operator !=(ColorVector left, ColorVector right) { return !(left == right); } /// /// 大于 /// /// 左值 /// 右值 /// A,R,G,B全部大于返回true,否则返回false public static bool operator >(ColorVector left, ColorVector right) { return left.A > right.A && left.R > right.R && left.G > right.G && left.B > right.B; } /// /// 大于等于 /// /// 左值 /// 右值 /// A,R,G,B全部大于等于返回true,否则返回false public static bool operator >=(ColorVector left, ColorVector right) { return left.A >= right.A && left.R >= right.R && left.G >= right.G && left.B >= right.B; } /// /// 小于 /// /// 左值 /// 右值 /// A,R,G,B全部小于返回true,否则返回false public static bool operator <(ColorVector left, ColorVector right) { return left.A < right.A && left.R < right.R && left.G < right.G && left.B < right.B; } /// /// 小于等于 /// /// 左值 /// 右值 /// A,R,G,B全部小于等于返回true,否则返回false public static bool operator <=(ColorVector left, ColorVector right) { return left.A <= right.A && left.R <= right.R && left.G <= right.G && left.B <= right.B; } /// /// 两个颜色向量相加 /// /// 左值 /// 右值 /// 返回新颜色向量 public static ColorVector operator +(ColorVector left, ColorVector right) { return new ColorVector(left.A + right.A, left.R + right.R, left.G + right.G, left.B + right.B); } /// /// 颜色加上颜色向量 /// /// 颜色 /// 颜色向量 /// 返回新颜色 public static Color operator +(Color left, ColorVector right) { return Color.FromArgb(MathEx.Clamp(left.A + right.A, (byte)0, (byte)255), MathEx.Clamp(left.R + right.R, (byte)0, (byte)255), MathEx.Clamp(left.G + right.G, (byte)0, (byte)255), MathEx.Clamp(left.B + right.B, (byte)0, (byte)255)); } /// /// 两个颜色向量相减 /// /// 左值 /// 右值 /// 返回新颜色向量 public static ColorVector operator -(ColorVector left, ColorVector right) { return new ColorVector(left.A - right.A, left.R - right.R, left.G - right.G, left.B - right.B); } /// /// 颜色减去颜色向量 /// /// 颜色 /// 颜色向量 /// 返回新颜色 public static Color operator -(Color left, ColorVector right) { return Color.FromArgb(MathEx.Clamp(left.A - right.A, (byte)0, (byte)255), MathEx.Clamp(left.R - right.R, (byte)0, (byte)255), MathEx.Clamp(left.G - right.G, (byte)0, (byte)255), MathEx.Clamp(left.B - right.B, (byte)0, (byte)255)); } /// /// 颜色向量乘以浮点数 /// /// 颜色向量 /// 浮点数 /// 返回新颜色向量 public static ColorVector operator *(ColorVector left, float right) { return new ColorVector((int)(left.A * right), (int)(left.R * right), (int)(left.G * right), (int)(left.B * right)); } /// /// 浮点数乘以颜色向量 /// /// 浮点数 /// 颜色向量 /// 返回新颜色向量 public static ColorVector operator *(float left, ColorVector right) { return new ColorVector((int)(left * right.A), (int)(left * right.R), (int)(left * right.G), (int)(left * right.B)); } /// /// 颜色向量乘以整数 /// /// 颜色向量 /// 浮点数 /// 返回新颜色向量 public static ColorVector operator *(ColorVector left, int right) { return new ColorVector(left.A * right, left.R * right, left.G * right, left.B * right); } /// /// 整数乘以颜色向量 /// /// 整数 /// 颜色向量 /// 返回新颜色向量 public static ColorVector operator *(int left, ColorVector right) { return new ColorVector(left * right.A, left * right.R, left * right.G, left * right.B); } /// /// 颜色向量除以浮点数 /// /// 颜色向量 /// 浮点数 /// 返回新颜色向量 public static ColorVector operator /(ColorVector left, float right) { return new ColorVector((int)(left.A / right), (int)(left.R / right), (int)(left.G / right), (int)(left.B / right)); } /// /// 浮点数除以颜色向量 /// /// 浮点数 /// 颜色向量 /// 返回新颜色向量 public static ColorVector operator /(float left, ColorVector right) { return new ColorVector((int)(left / right.A), (int)(left / right.R), (int)(left / right.G), (int)(left / right.B)); } /// /// 颜色向量除以整数 /// /// 颜色向量 /// 整数 /// 返回新颜色向量 public static ColorVector operator /(ColorVector left, int right) { return new ColorVector(left.A / right, left.R / right, left.G / right, left.B / right); } /// /// 整数除以颜色向量 /// /// 整数 /// 颜色向量 /// 返回新颜色向量 public static ColorVector operator /(int left, ColorVector right) { return new ColorVector(left / right.A, left / right.R, left / right.G, left / right.B); } #endregion } }