如何将RGBA css颜色格式转换为十六进制格式
本文关键字:格式 转换 十六进制 颜色 css RGBA | 更新日期: 2023-09-27 17:58:09
在我的selenium代码中,我需要验证背景的颜色代码是#192856。但当我得到该元素的CSS属性时,它会以rgba格式为我提供颜色。现在我需要获取十六进制值本身的值。我该怎么做?
quickLinkstab.GetCssValue("background-color")
上面给出了"rgba(25,40,86,1)"的值,即rgba值。有什么办法可以把它转换回十六进制吗?或者我可以得到十六进制本身的值?
我也试过下面的代码
string colorcode = menuColor;
int argb = Int32.Parse(colorcode.Replace("#", ""), NumberStyles.HexNumber);
Color clr = Color.FromArgb(argb);
int r = Convert.ToInt16(clr.R);
int g = Convert.ToInt16(clr.G);
int b = Convert.ToInt16(clr.B);
int a = Convert.ToInt16(clr.A);
string x = string.Format("rgba({0}, {1}, {2}, {3});", r, g, b,a);
但这个给了我一个值,比如"rgba(25,40,86,0);"。"a"值的差异。就像我的代码给我0表示"a",但cssvalue是1。
我更倾向于直接获得十六进制值的解决方案,或者如果不可能,则将rgba转换为十六进制。
以下代码涵盖十六进制格式、rgb和rgba。
public static class ColorHelper
{
public static Color ParseColor(string cssColor)
{
cssColor = cssColor.Trim();
if (cssColor.StartsWith("#"))
{
return ColorTranslator.FromHtml(cssColor);
}
else if (cssColor.StartsWith("rgb")) //rgb or argb
{
int left = cssColor.IndexOf('(');
int right = cssColor.IndexOf(')');
if (left < 0 || right < 0)
throw new FormatException("rgba format error");
string noBrackets = cssColor.Substring(left + 1, right - left - 1);
string[] parts = noBrackets.Split(',');
int r = int.Parse(parts[0], CultureInfo.InvariantCulture);
int g = int.Parse(parts[1], CultureInfo.InvariantCulture);
int b = int.Parse(parts[2], CultureInfo.InvariantCulture);
if (parts.Length == 3)
{
return Color.FromArgb(r, g, b);
}
else if (parts.Length == 4)
{
float a = float.Parse(parts[3], CultureInfo.InvariantCulture);
return Color.FromArgb((int)(a * 255), r, g, b);
}
}
throw new FormatException("Not rgb, rgba or hexa color string");
}
}
预期结果:
[TestClass]
public class ColorParserTest
{
[TestMethod]
public void TestParseColorRGB()
{
Color c = ColorHelper.ParseColor("rgb(110,120,130)");
Assert.AreEqual(110, c.R);
Assert.AreEqual(120, c.G);
Assert.AreEqual(130, c.B);
Assert.AreEqual(255, c.A);
}
[TestMethod]
public void TestParseColorRGBA()
{
Color c = ColorHelper.ParseColor("rgba(110,120,130,0.5)");
Assert.AreEqual(110, c.R);
Assert.AreEqual(120, c.G);
Assert.AreEqual(130, c.B);
Assert.AreEqual(127, c.A);
}
[TestMethod]
public void TestParseColorHexa()
{
Color c = ColorHelper.ParseColor("#192856");
Assert.AreEqual(25, c.R);
Assert.AreEqual(40, c.G);
Assert.AreEqual(86, c.B);
Assert.AreEqual(255, c.A);
}
}
使用系统。绘画颜色转换器
string htmlColor = ColorTranslator.ToHtml(myColor);
使用字符串。格式化
//RGB
String.Format("#{0:X2}{1:X2}{2:X2}", colorValue.R,colorValue.G,colorValue.B);
//RGBA
var strigifiedColor = String. Format("#{0:X2}{1:X2}{2:X2}{3:X2}", colorValue.R, colorValue.G, colorValue.B, colorValue.A);
扩展
public static class ColorExtension
{
public static string HexFormat(this Color colorValue)
{
return String.Format("#{0:X2}{1:X2}{2:X2}{3:X2}", colorValue.A, colorValue.R, colorValue.G, colorValue.B);
}
}
我对Thomas的回答进行了扩展,以涵盖#RGBA/#RRGGBBAA格式。
你可能想以不同的方式处理错误,我更喜欢只返回Color。如果无法解析输入,则为空。
(在Typescript中添加单元测试导致了对一些C#代码的研究,这导致ColorTranslator完全不知道alpha值——不要假设任何东西,测试所有东西!)
public static ColorUtils
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1031:Do not catch general exception types", Justification = "ColorTranslator throws System.Exception")]
public static Color HtmlToColor(string htmlColor)
{
Guard.ArgumentIsNotNull(htmlColor, nameof(htmlColor));
var htmlLowerCase = htmlColor.ToLower().Trim();
try
{
if (htmlLowerCase.StartsWith("rgb"))
{
return ArgbToColor(htmlLowerCase);
}
else if (htmlLowerCase.StartsWith("#"))
{
return HexToColor(htmlLowerCase);
}
else
{
// Fallback to ColorTranslator for named colors, e.g. "Black", "White" etc.
return ColorTranslator.FromHtml(htmlLowerCase);
}
}
catch
{
// ColorTranslator throws System.Exception, don't really care what the actual error is.
}
return Color.Empty;
}
private static Color HexToColor(string htmlLowerCase)
{
var len = htmlLowerCase.Length;
// #RGB
if (len == 4)
{
var r = Convert.ToInt32(htmlLowerCase.Substring(1, 1), 16);
var g = Convert.ToInt32(htmlLowerCase.Substring(2, 1), 16);
var b = Convert.ToInt32(htmlLowerCase.Substring(3, 1), 16);
return Color.FromArgb(r + (r * 16), g + (g * 16), b + (b * 16));
}
// #RGBA
else if (len == 5)
{
var r = Convert.ToInt32(htmlLowerCase.Substring(1, 1), 16);
var g = Convert.ToInt32(htmlLowerCase.Substring(2, 1), 16);
var b = Convert.ToInt32(htmlLowerCase.Substring(3, 1), 16);
var a = Convert.ToInt32(htmlLowerCase.Substring(4, 1), 16);
return Color.FromArgb(a + (a * 16), r + (r * 16), g + (g * 16), b + (b * 16));
}
// #RRGGBB
else if (len == 7)
{
return Color.FromArgb(
Convert.ToInt32(htmlLowerCase.Substring(1, 2), 16),
Convert.ToInt32(htmlLowerCase.Substring(3, 2), 16),
Convert.ToInt32(htmlLowerCase.Substring(5, 2), 16));
}
// #RRGGBBAA
else if (len == 9)
{
return Color.FromArgb(
Convert.ToInt32(htmlLowerCase.Substring(7, 2), 16),
Convert.ToInt32(htmlLowerCase.Substring(1, 2), 16),
Convert.ToInt32(htmlLowerCase.Substring(3, 2), 16),
Convert.ToInt32(htmlLowerCase.Substring(5, 2), 16));
}
return Color.Empty;
}
private static Color ArgbToColor(string htmlLowerCase)
{
int left = htmlLowerCase.IndexOf('(');
int right = htmlLowerCase.IndexOf(')');
if (left < 0 || right < 0)
{
return Color.Empty;
}
string noBrackets = htmlLowerCase.Substring(left + 1, right - left - 1);
string[] parts = noBrackets.Split(',');
int r = int.Parse(parts[0], CultureInfo.InvariantCulture);
int g = int.Parse(parts[1], CultureInfo.InvariantCulture);
int b = int.Parse(parts[2], CultureInfo.InvariantCulture);
if (parts.Length == 3)
{
return Color.FromArgb(r, g, b);
}
else if (parts.Length == 4)
{
float a = float.Parse(parts[3], CultureInfo.InvariantCulture);
return Color.FromArgb((int)(a * 255), r, g, b);
}
return Color.Empty;
}
}
测试:
[TestMethod]
public void ColorUtils_HtmlToColor()
{
Assert.AreEqual(Color.FromArgb(0x11, 0x22, 0x33), ColorUtils.HtmlToColor("#123"), "#123 (without alpha channel)");
Assert.AreEqual(Color.FromArgb(0x11, 0x22, 0x33), ColorUtils.HtmlToColor("#112233"), "#112233 (without alpha channel)");
Assert.AreEqual(Color.FromArgb(0x44, 0x11, 0x22, 0x33), ColorUtils.HtmlToColor("#1234"), "#1234 (alpha channel)");
Assert.AreEqual(Color.FromArgb(0x44, 0x11, 0x22, 0x33), ColorUtils.HtmlToColor("#11223344"), "#11223344 (alpha channel)");
Assert.AreEqual(Color.FromArgb(127, 11, 22, 33), ColorUtils.HtmlToColor("rgba(11,22,33,0.5)"), "rgba(11,22,33,0.5) (alpha channel)");
Assert.AreEqual(Color.FromArgb(11, 22, 33), ColorUtils.HtmlToColor("rgb(11,22,33)"), "rgb(11,22,33) (alpha channel)");
Assert.AreEqual(Color.Red, ColorUtils.HtmlToColor("red"), "red (named color)");
Assert.AreEqual(Color.White, ColorUtils.HtmlToColor("white"), "white (named color)");
Assert.AreEqual(Color.Blue, ColorUtils.HtmlToColor("blue"), "blue (named color)");
Assert.AreEqual(Color.Empty, ColorUtils.HtmlToColor("invalid"), "invalid");
Assert.AreEqual(Color.Empty, ColorUtils.HtmlToColor("#invalid"), "#invalid");
Assert.AreEqual(Color.Empty, ColorUtils.HtmlToColor("rgb(invalid)"), "rgb(invalid)");
Assert.AreEqual(Color.Empty, ColorUtils.HtmlToColor("rgba(invalid)"), "rgba(invalid)");
Assert.AreEqual(Color.Empty, ColorUtils.HtmlToColor("rgba(invalid,invalid)"), "rgba(invalid,invalid)");
Assert.AreEqual(Color.Empty, ColorUtils.HtmlToColor("rgb(11,22,333)"), "rgb(11,22,333) (value out of range)");
Assert.AreEqual(Color.Empty, ColorUtils.HtmlToColor("rgba(11,22,333,0.5)"), "rgb(11,22,333,0.5) (value out of range)");
}
这样就可以了。
public static string ConvertRgbaToHex(string rgba)
{
if (!Regex.IsMatch(rgba, @"rgba'(('d{1,3},'s*){3}(0('.'d+)?|1)')"))
throw new FormatException("rgba string was in a wrong format");
var matches = Regex.Matches(rgba, @"'d+");
StringBuilder hexaString = new StringBuilder("#");
for(int i = 0; i < matches.Count - 1; i++)
{
int value = Int32.Parse(matches[i].Value);
hexaString.Append(value.ToString("X"));
}
return hexaString.ToString();
}
测试用例:
public class Program
{
static void Main(string[] args)
{
// Output: #192856
Console.WriteLine(ConvertRgbaToHex("rgba(25, 40, 86, 1)"));
Console.Read();
}
public static string ConvertRgbaToHex(string rgba)
{
if (!Regex.IsMatch(rgba, @"rgba'(('d{1,3},'s*){3}(0('.'d+)?|1)')"))
throw new FormatException("rgba string was in a wrong format");
var matches = Regex.Matches(rgba, @"'d+");
StringBuilder hexaString = new StringBuilder("#");
for(int i = 0; i < matches.Count - 1; i++)
{
int value = Int32.Parse(matches[i].Value);
hexaString.Append(value.ToString("X"));
}
return hexaString.ToString();
}
}
下面的代码从元素中选择样式属性,将rgb值转换为十六进制格式,然后比较该值。
string color = GetElement(LocateBy.XPath, "XpathOfTheElement").GetAttribute("style").ToString();
string[] colorvalue1 = color.Split('(');
string[] colorvalue2 = colorvalue1[1].Split(')');
string colorvalue = colorvalue2[0].ToString();
string[] ColorCodeRGBValue = colorvalue.Split(',');
Color myColor = Color.FromArgb(Convert.ToInt32(ColorCodeRGBValue[0]), Convert.ToInt32(ColorCodeRGBValue[1]), Convert.ToInt32(ColorCodeRGBValue[2]));
string hexValue = myColor.R.ToString("X2") + myColor.G.ToString("X2") + myColor.B.ToString("X2");
Assert.AreEqual(hexValue , CsvReader.ColorCode,"Color codes are not equal");
Color有一个可用的Selenium库:
import org.openqa.selenium.support.Color;
String rgba = "rgba(1,1,1,1)";
Color color = Color.fromString(rgba);
System.out.println("hex value = " + color.asHex());
双向转换。我进行了开发和测试。
public static string RgbaToHex(string value)
{
if (string.IsNullOrEmpty(value))
return null;
Color color;
value = value.Trim();
if (value.StartsWith("#"))
color = ColorTranslator.FromHtml(value);
else
{
if (!value.StartsWith("rgba"))
throw new FormatException("Not rgba string");
var left = value.IndexOf('(');
var right = value.IndexOf(')');
if (left < 0 || right < 0)
throw new FormatException("rgba format error");
var noBrackets = value.Substring(left + 1, right - left - 1);
var parts = noBrackets.Split(',');
var r = int.Parse(parts[0], CultureInfo.InvariantCulture);
var g = int.Parse(parts[1], CultureInfo.InvariantCulture);
var b = int.Parse(parts[2], CultureInfo.InvariantCulture);
switch (parts.Length)
{
case 3:
color = Color.FromArgb(r, g, b);
break;
case 4:
{
var a = float.Parse(parts[3], CultureInfo.InvariantCulture);
color = Color.FromArgb((int)(a * 255), r, g, b);
break;
}
default:
throw new FormatException("Not rgba string");
}
}
return "#" + color.A.ToString("X2") + color.R.ToString("X2") + color.G.ToString("X2") + color.B.ToString("X2");
}
public static string HexToRgba(string value)
{
if (string.IsNullOrEmpty(value))
return null;
var argb = int.Parse(value.Replace("#", ""), NumberStyles.HexNumber);
var clr = Color.FromArgb(argb);
int r = Convert.ToInt16(clr.R);
int g = Convert.ToInt16(clr.G);
int b = Convert.ToInt16(clr.B);
int a = Convert.ToInt16(clr.A);
var trans = Math.Round((double)a / 255, 2).ToString("N2").Replace(",", ".");
return $"rgba({r}, {g}, {b}, {trans})";
}