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

在我的 Java 应用程序中,我能够获得 JButtonColor(红、绿、蓝) ; 我已经将这些值存储在三个 int中。

如何将这些 RGB 值转换成包含等效十六进制表示的 String? 比如 #0033fA

127032 次浏览
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;

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).

A one liner but without String.format for all RGB colors:

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. Note, that this is valid (as asked in the question) for all RGB colors.

When you have ARGB colors you can use:

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. I benchmarked the ARGB solution and compared it with String.format() and the toHexString solution has a much higher performance:

enter image description here

This is an adapted version of the answer given by Vivien Barousse with the update from Vulcan applied. In this example I use sliders to dynamically retreive the RGB values from three sliders and display that color in a rectangle. Then in method toHex() I use the values to create a color and display the respective Hex color code.

This example does not include the proper constraints for the 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. This solution works perfectly and was super simple to implement.

Convert a java.awt.Color to a 24-bit hexadecimal RGB representation even if alpha channel value is zero (e.g. 0000ff):

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

For uppercase (e.g. 0000FF) :

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

slightly modified versions for RGBA from How to convert a color integer to a hex String in Android? and How to code and decode RGB to Hex

    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. 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:

   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); 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. So as far as I can see we need an improved use of Integer.toHexString to handle those cases. 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); The result will be #C0C0C0C witch is wrong.

Here is a 2 line version that also encodes the alpha value. These other examples are too verbose.

int rgba = (color.getRGB() << 8) | color.getAlpha();
return String.format("#%08X", rgba);