简体   繁体   English

将 RGB 颜色值转换为十六进制字符串

[英]Convert a RGB Color Value to a Hexadecimal String

In my Java application, I was able to get the Color of a JButton in terms of red, green and blue;在我的 Java 应用程序中,我能够以红色、绿色和蓝色的形式获得JButtonColor I have stored these values in three int s.我已将这些值存储在三个int中。

How do I convert those RGB values into a String containing the equivalent hexadecimal representation?如何将这些 RGB 值转换为包含等效十六进制表示的String Such as #0033fA#0033fA

You can use您可以使用

String hex = String.format("#%02x%02x%02x", r, g, b);  

Use capital X's if you want your resulting hex-digits to be capitalized ( #FFFFFF vs. #ffffff ).如果您希望将生成的十六进制数字大写( #FFFFFF vs. #ffffff ),请使用大写 X。

A one liner but without String.format for all RGB colors:一个衬里,但没有适用于所有RGB颜色的String.format

Color your_color = new Color(128,128,128);

String hex = "#"+Integer.toHexString(your_color.getRGB()).substring(2);

You can add a .toUpperCase() if you want to switch to capital letters.如果要切换到大写字母,可以添加.toUpperCase() Note, that this is valid (as asked in the question) for all RGB colors.请注意,这对于所有 RGB 颜色都是有效的(如问题中所述)。

When you have ARGB colors you can use:当你有ARGB颜色时,你可以使用:

Color your_color = new Color(128,128,128,128);

String buf = Integer.toHexString(your_color.getRGB());
String hex = "#"+buf.substring(buf.length()-6);

A one liner is theoretically also possible but would require to call toHexString twice.理论上,一个班轮也是可能的,但需要调用 toHexString 两次。 I benchmarked the ARGB solution and compared it with String.format() and the toHexString solution has a much higher performance:我对 ARGB 解决方案进行了基准测试,并将其与String.format()进行了比较,而toHexString解决方案具有更高的性能:

在此处输入图像描述

Random ra = new Random();
int r, g, b;
r=ra.nextInt(255);
g=ra.nextInt(255);
b=ra.nextInt(255);
Color color = new Color(r,g,b);
String hex = Integer.toHexString(color.getRGB() & 0xffffff);
if (hex.length() < 6) {
    hex = "0" + hex;
}
hex = "#" + hex;

Convert a java.awt.Color to a 24-bit hexadecimal RGB representation even if alpha channel value is zero (eg 0000ff ):即使 alpha 通道值为零(例如0000ff ),也将java.awt.Color转换为 24 位十六进制 RGB 表示:

String.format("%06x", 0xFFFFFF & Color.BLUE.getRGB())

For uppercase (eg 0000FF ) :对于大写(例如0000FF ):

String.format("%06X", 0xFFFFFF & Color.BLUE.getRGB())

This is an adapted version of the answer given by Vivien Barousse with the update from Vulcan applied.这是Vivien Barousse给出的答案的改编版本,应用了Vulcan的更新。 In this example I use sliders to dynamically retreive the RGB values from three sliders and display that color in a rectangle.在此示例中,我使用滑块从三个滑块中动态检索 RGB 值并在矩形中显示该颜色。 Then in method toHex() I use the values to create a color and display the respective Hex color code.然后在 toHex() 方法中,我使用这些值创建颜色并显示相应的十六进制颜色代码。

This example does not include the proper constraints for the GridBagLayout.此示例不包括 GridBagLayout 的正确约束。 Though the code will work, the display will look strange.虽然代码可以工作,但显示会看起来很奇怪。

public class HexColor
{

  public static void main (String[] args)
  {
   JSlider sRed = new JSlider(0,255,1);
   JSlider sGreen = new JSlider(0,255,1);
   JSlider sBlue = new JSlider(0,255,1);
   JLabel hexCode = new JLabel();
   JPanel myPanel = new JPanel();
   GridBagLayout layout = new GridBagLayout();
   JFrame frame = new JFrame();

   //set frame to organize components using GridBagLayout 
   frame.setLayout(layout);

   //create gray filled rectangle 
   myPanel.paintComponent();
   myPanel.setBackground(Color.GRAY);

   //In practice this code is replicated and applied to sGreen and sBlue. 
   //For the sake of brevity I only show sRed in this post.
   sRed.addChangeListener(
         new ChangeListener()
         {
             @Override
             public void stateChanged(ChangeEvent e){
                 myPanel.setBackground(changeColor());
                 myPanel.repaint();
                 hexCode.setText(toHex());
         }
         }
     );
   //add each component to JFrame
   frame.add(myPanel);
   frame.add(sRed);
   frame.add(sGreen);
   frame.add(sBlue);
   frame.add(hexCode);
} //end of main

  //creates JPanel filled rectangle
  protected void paintComponent(Graphics g)
  {
      super.paintComponent(g);
      g.drawRect(360, 300, 10, 10);
      g.fillRect(360, 300, 10, 10);
  }

  //changes the display color in JPanel
  private Color changeColor()
  {
    int r = sRed.getValue();
    int b = sBlue.getValue();
    int g = sGreen.getValue();
    Color c;
    return  c = new Color(r,g,b);
  }

  //Displays hex representation of displayed color
  private String toHex()
  {
      Integer r = sRed.getValue();
      Integer g = sGreen.getValue();
      Integer b = sBlue.getValue();
      Color hC;
      hC = new Color(r,g,b);
      String hex = Integer.toHexString(hC.getRGB() & 0xffffff);
      while(hex.length() < 6){
          hex = "0" + hex;
      }
      hex = "Hex Code: #" + hex;
      return hex;
  }
}

A huge thank you to both Vivien and Vulcan.非常感谢 Vivien 和 Vulcan。 This solution works perfectly and was super simple to implement.该解决方案完美运行,实施起来超级简单。

slightly modified versions for RGBA from How to convert a color integer to a hex String in Android? How to convert a color integer to a hex String in Android? 对 RGBA 的略微修改版本? and How to code and decode RGB to Hex以及如何将 RGB 编码和解码为十六进制

    public static String ColorToHex (Color color) {
    int red = color.getRed();
    int green = color.getGreen();
    int blue = color.getBlue();
    int alpha = color.getAlpha(); 

    String redHex = To00Hex(red);
    String greenHex = To00Hex(green);
    String blueHex = To00Hex(blue);
    String alphaHex = To00Hex(alpha);

    // hexBinary value: RRGGBBAA
    StringBuilder str = new StringBuilder("#");
    str.append(redHex);
    str.append(greenHex);
    str.append(blueHex);
    str.append(alphaHex);

    return str.toString();
}

private static String To00Hex(int value) {
    String hex = "00".concat(Integer.toHexString(value));
    hex=hex.toUpperCase();
    return hex.substring(hex.length()-2, hex.length());
} 

another way, this one could be related to the benchmark above:另一种方式,这可能与上述基准有关:

public static String rgbToHex (Color color) {

   String hex = String.format("#%02x%02x%02x%02x", color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha() );
   hex=hex.toUpperCase();
       return hex;
}

a very simple benchmark shows that solution with String.format is 2+ times slower than StringBuilder for 10 million color conversions.一个非常简单的基准测试表明,对于 1000 万次颜色转换,使用 String.format 的解决方案比 StringBuilder 慢 2 倍以上。 For small amount of objects you cannot really see a difference.对于少量的物体,你看不出有什么区别。

I am not an expert so my opinion is subjective.我不是专家,所以我的意见是主观的。 I'm posting the benchmark code for any use, replace methods rgbToHex, rgbToHex2 with those you want to test:我发布了任何用途的基准代码,将方法 rgbToHex, rgbToHex2 替换为您要测试的方法:

   public static void benchmark /*ColorToHex*/ () {
       
 Color color = new Color(12,12,12,12);
   
     ArrayList<Color> colorlist = new ArrayList<Color>();
    // a list filled with a color i times
    for (int i = 0; i < 10000000; i++) {
      
        colorlist.add((color));
    }
   
   ArrayList<String> hexlist = new ArrayList<String>();
   System.out.println("START TIME... " + ZonedDateTime.now().format(DateTimeFormatter.ISO_LOCAL_TIME) + "  TEST CASE 1...");
        for (int i = 0; i < colorlist.size(); i++) {
        hexlist.add(rgbToHex(colorlist.get(i)));
    }
        System.out.println("END TIME... " + ZonedDateTime.now().format(DateTimeFormatter.ISO_LOCAL_TIME) + "  TEST CASE 1...");
        System.out.println("hexlist.get(0)... "+hexlist.get(0));
        
     ArrayList<String> hexlist2 = new ArrayList<String>();
   System.out.println("START TIME... " + ZonedDateTime.now().format(DateTimeFormatter.ISO_LOCAL_TIME) + " TEST CASE 2...");
        for (int i = 0; i < colorlist.size(); i++) {
        hexlist2.add(rgbToHex1(colorlist.get(i)));
    }
     System.out.println("END TIME... " + ZonedDateTime.now().format(DateTimeFormatter.ISO_LOCAL_TIME) + "  TEST CASE 2..."); 
     System.out.println("hexlist2.get(0)... "+hexlist2.get(0));

    }

it seems that there are issues with Integer.toHexString(color.getRGB()) try it with Color color = new Color(0,0,0,0);似乎Integer.toHexString(color.getRGB())存在问题 尝试使用Color color = new Color(0,0,0,0); and you will find out that we have subtraction of zeros.你会发现我们有减零。 #0 instead of #00000000 and we need all digits in order to have valid hex color values, 6 or 8 if with Alpha. #0 而不是 #00000000,我们需要所有数字才能获得有效的十六进制颜色值,如果使用 Alpha,则为 6 或 8。 So as far as I can see we need an improved use of Integer.toHexString to handle those cases.据我所知,我们需要改进使用 Integer.toHexString 来处理这些情况。 There should be other cases that cannot handle leading zeros at hex values.应该有其他情况无法处理十六进制值的前导零。 For example try with #0c0c0c0c that corresponds to Color color = new Color(12,12,12,12);例如,尝试使用对应于Color color = new Color(12,12,12,12);#0c0c0c0c The result will be #C0C0C0C witch is wrong.结果将是#C0C0C0C 女巫是错误的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM