将 BGRA 8 位十六进制字符串转换为 System.Drawing.Color
Converting BGRA 8-Bit Hexadecimal string into System.Drawing.Color
我有从 Delphi 应用程序获得的 BGRA 格式的颜色。我将这些作为 8 位字符串读取到我的 C# 应用程序中。现在我尝试将它们转换为 C# 颜色格式。我得到的字符串如下所示:
string color = "[=11=]FF00FF";
我尝试重新转换颜色,然后将其转换为 Int 以将其转换为 System.Drawing
颜色
private Color ConvertColorFromBgra(string color)
{
string argb = "#";
var bgra = FunctionLibrary.SplitByLength(color.Replace("$", ""), 2);
foreach (var value in bgra.Revert())
{
argb += value;
}
return Color.FromArgb(Convert.ToInt32(argb, 16));
}
其中 SplitByLenght 是我在 SO 上找到的函数(我从另一个 Class 调用):
public static IEnumerable<string> SplitByLength(this string str, int maxLength)
{
for (int index = 0; index < str.Length; index += maxLength)
{
yield return str.Substring(index, Math.Min(maxLength, str.Length - index));
}
}
但不知何故它不起作用,我收到错误消息:
System.FormatException: 'Could not find any recognizable digits.
我觉得字符串没有按预期转换为 Int,但我没有找到任何修复方法。你能帮我解决这个问题,或者有其他更好的方法来解决这个问题吗?
我显然找到了解决方案,只需要使用 ColorTranslator.FromHtml(argb)
而不是 Color.FromArgb(Convert.ToInt32(argb, 16))
为避免字符串操作,您可以使用 string.Substring(1)
删除第一个字符,然后使用接受特定基数 (16
) 的 Convert.ToInt32() 重载将字符串转换为LE int
.
BitConverter.GetBytes() 然后可用于从转换后的 int 中提取字节并反转顺序。
► 您可能希望在反转字节顺序之前添加一个检查:如果 BitConverter.IsLittleEndian returns 为假,我们已经在使用 BigEndian 处理器,因此在这种情况下我们不会反转顺序。
之后重新组合 int
值并使用 Color.FromArgb to return a Color that includes an Alpha channel or ColorTranslator.FromWin32 忽略它(将 Alpha 通道设置为 255
无论如何:例如,如果您需要在不支持颜色透明度的控件)。
我将此方法添加为 Sting 扩展 (string.ToARGBColor(bool)
)。随意命名。
public static class StringsExtensions
{
public static Color ToARGBColor(this string hexColor, bool includeAlpha)
{
int ci = BitConverter.ToInt32(BitConverter.GetBytes(
Convert.ToInt32(hexColor.Substring(1), 16)).Reverse().ToArray(), 0);
return includeAlpha ? Color.FromArgb(ci) : ColorTranslator.FromWin32(ci);
}
}
因此您可以将其命名为:
string colorString = "[=11=]FF00AA";
Color colorWithAlpha = colorString.ToARGBColor(true);
Color colorNoAlpha = colorString.ToARGBColor(false);
使用另一种经典的BigEndian到LittleEndian的转换方法:
(应该会稍微快一点,可以试驾一下)
byte[] b = BitConverter.GetBytes(Convert.ToInt32(colorString.Substring(1), 16));
int ci = (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | b[3];
Color c = Color.FromArgb(ci);
我有从 Delphi 应用程序获得的 BGRA 格式的颜色。我将这些作为 8 位字符串读取到我的 C# 应用程序中。现在我尝试将它们转换为 C# 颜色格式。我得到的字符串如下所示:
string color = "[=11=]FF00FF";
我尝试重新转换颜色,然后将其转换为 Int 以将其转换为 System.Drawing
颜色
private Color ConvertColorFromBgra(string color)
{
string argb = "#";
var bgra = FunctionLibrary.SplitByLength(color.Replace("$", ""), 2);
foreach (var value in bgra.Revert())
{
argb += value;
}
return Color.FromArgb(Convert.ToInt32(argb, 16));
}
其中 SplitByLenght 是我在 SO 上找到的函数(我从另一个 Class 调用):
public static IEnumerable<string> SplitByLength(this string str, int maxLength)
{
for (int index = 0; index < str.Length; index += maxLength)
{
yield return str.Substring(index, Math.Min(maxLength, str.Length - index));
}
}
但不知何故它不起作用,我收到错误消息:
System.FormatException: 'Could not find any recognizable digits.
我觉得字符串没有按预期转换为 Int,但我没有找到任何修复方法。你能帮我解决这个问题,或者有其他更好的方法来解决这个问题吗?
我显然找到了解决方案,只需要使用 ColorTranslator.FromHtml(argb)
而不是 Color.FromArgb(Convert.ToInt32(argb, 16))
为避免字符串操作,您可以使用 string.Substring(1)
删除第一个字符,然后使用接受特定基数 (16
) 的 Convert.ToInt32() 重载将字符串转换为LE int
.
BitConverter.GetBytes() 然后可用于从转换后的 int 中提取字节并反转顺序。
► 您可能希望在反转字节顺序之前添加一个检查:如果 BitConverter.IsLittleEndian returns 为假,我们已经在使用 BigEndian 处理器,因此在这种情况下我们不会反转顺序。
之后重新组合 int
值并使用 Color.FromArgb to return a Color that includes an Alpha channel or ColorTranslator.FromWin32 忽略它(将 Alpha 通道设置为 255
无论如何:例如,如果您需要在不支持颜色透明度的控件)。
我将此方法添加为 Sting 扩展 (string.ToARGBColor(bool)
)。随意命名。
public static class StringsExtensions
{
public static Color ToARGBColor(this string hexColor, bool includeAlpha)
{
int ci = BitConverter.ToInt32(BitConverter.GetBytes(
Convert.ToInt32(hexColor.Substring(1), 16)).Reverse().ToArray(), 0);
return includeAlpha ? Color.FromArgb(ci) : ColorTranslator.FromWin32(ci);
}
}
因此您可以将其命名为:
string colorString = "[=11=]FF00AA";
Color colorWithAlpha = colorString.ToARGBColor(true);
Color colorNoAlpha = colorString.ToARGBColor(false);
使用另一种经典的BigEndian到LittleEndian的转换方法:
(应该会稍微快一点,可以试驾一下)
byte[] b = BitConverter.GetBytes(Convert.ToInt32(colorString.Substring(1), 16));
int ci = (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | b[3];
Color c = Color.FromArgb(ci);