我有一个算法将RGB555值转换为System.Drawing.Color对象;
public static Color ToColor(ushort color)
{
int a = color & 0x8000;
int r = color & 0x7C00;
int g = color & 0x03E0;
int b = color & 0x1F;
int rgb = (r << 9) | (g << 6) | (b << 3);
return Color.FromArgb((a * 0x1FE00) | rgb | ((rgb >> 5) & 0x070707));
}
一位朋友为我写了这个方法(按位移位有点过头了),反转这段代码最有效的方法是什么?
感谢您的任何建议,我一直在努力寻找答案,所以任何见解都会让我感到清新!
修改的
这个问题已经解决了一段时间,但我想我会回来并用最终结果更新我的帖子 - 感谢所有回答的人!
public struct Color555 : IEquatable<Color555>, IComparable<Color555>, IEquatable<ushort>, IComparable<ushort>
{
public static readonly Color555 MinValue = ushort.MinValue;
public static readonly Color555 MaxValue = ushort.MaxValue;
private readonly ushort _Value;
public Color555(Color value)
{
uint c = (uint)value.ToArgb();
_Value = (ushort)(((c >> 16) & 0x8000 | (c >> 9) & 0x7C00 | (c >> 6) & 0x03E0 | (c >> 3) & 0x1F));
}
public Color555(ushort value)
{
_Value = value;
}
public override int GetHashCode()
{
return _Value.GetHashCode();
}
public override bool Equals(object obj)
{
return (obj is ushort && Equals((ushort)obj)) || (obj is Color555 && Equals((Color555)obj));
}
public bool Equals(ushort other)
{
return _Value == other;
}
public bool Equals(Color555 other)
{
return _Value == other._Value;
}
public int CompareTo(Color555 other)
{
return _Value.CompareTo(other._Value);
}
public int CompareTo(ushort other)
{
return _Value.CompareTo(other);
}
public override string ToString()
{
return String.Format("{0}", _Value);
}
public string ToString(string format)
{
return String.Format(format, _Value);
}
public string ToString(IFormatProvider provider)
{
return String.Format(provider, "{0}", _Value);
}
public string ToString(string format, IFormatProvider provider)
{
return String.Format(provider, format, _Value);
}
public int ToArgb()
{
return ToColor().ToArgb();
}
public Color ToColor()
{
int a = _Value & 0x8000;
int r = _Value & 0x7C00;
int g = _Value & 0x03E0;
int b = _Value & 0x1F;
int rgb = (r << 9) | (g << 6) | (b << 3);
return Color.FromArgb((a * 0x1FE00) | rgb | ((rgb >> 5) & 0x070707));
}
public static bool operator ==(Color555 l, Color555 r)
{
return l.Equals(r);
}
public static bool operator !=(Color555 l, Color555 r)
{
return !l.Equals(r);
}
public static implicit operator Color555(Color value)
{
return new Color555(value);
}
public static implicit operator Color555(ushort value)
{
return new Color555(value);
}
public static implicit operator ushort(Color555 value)
{
return value._Value;
}
}
答案 0 :(得分:2)
Color
每像素使用32位:每个8位用于alpha,红色,绿色和蓝色值。 (这意味着每个组件的值范围为0到255.)
RGB555颜色每像素使用5位(并且没有alpha通道),因此红色,绿色和蓝色都可以取0-31的值。
要从一个转换为另一个,我们需要将值0-255映射到值0-31。这显然是一个有损的过程;我们根本无法代表所有可能的Color
,并且许多不同的Color
值将映射到相同的Color555
。
最简单的映射就是截断,我们除以8并丢弃余数。这将0-7映射到0,8-15到1,...,248-255到31.这可以写为右向位移三位。
然后我们需要将这些值组合成一个16位值,这是通过将红色和绿色组件向左移动来实现的。
(您的示例代码似乎是基于高位设置Alpha通道,因此我们可以以相同的方式向后转换Alpha通道。在这种情况下,我们需要将256个可能的值映射到2:0或1.我选择将alpha通道分成两半;还有其他可能的映射。)
总而言之,它应该看起来像:
public Color555(Color color)
{
_Value = (ushort) ((color.A >= 128 ? 0x8000 : 0x0000) |
((color.R & 0xF8) << 7) | ((color.G & 0xF8) << 2) | (color.B >> 3));
}
答案 1 :(得分:-1)
为什么不使用它?
{
Color c = ColorTranslator.FromHtml("#555");
string s = ColorTranslator.ToHtml(c);
}