i have a code like this :
String hex = String.format("0x%02x%02x%02x", r * 0.5, green * 0.6, blue * 0.7));
0.5 and 0.6 and 0.7 are variables
and i want to set background color of a view from variable hex :
v.setBackgroundColor(Integer.parseInt(hex, 16));
When i try to convert it to Hexadecimal integer it throws exceptions like
java.lang.NumberFormatException
how can i do this?
0x causes NumberFormatException. try Integer.decode instead:
v.setBackgroundColor(Integer.decode(hex));
Read:
https://docs.oracle.com/javase/7/docs/api/java/lang/Integer.html#decode(java.lang.String)
There are potentially three problems with this code:
As #shiftpsh notes: Integer.parseInt does not understand the 0x prefix. There are two ways to solve this:
Use Integer.decode rather that Integer.parseInt.
Don't include the 0x prefix in the format.
The second potential problem is that %02x means hexadecimal, zero-padded with a minimum of two digits. But if any of r, green or blue were large enough, the resulting color value would be greater than 255, and you would get more than 2 hex digits. That would result in an incorrect RGB value when the string is decoded.
I am rather surprised that %02x works for an argument like r * 0.5. The latter is a double and according to my reading of the javadoc the x conversion is not applicable.
However, if the sole point of this code is to create and RGB value from r, green and blue, there is a significantly more efficient way to do it.
int r0 = ((int)(r * 0.5)) & 0xff;
int g0 = ((int)(green * 0.6)) & 0xff;
int b0 = ((int)(blue * 0.7)) & 0xff;
v.setBackgroundColor((r0 << 16) | (g0 << 8) | b0);
Alternatively, using android.graphics.Color.argb to do the RGB conversion should be just as efficient .... though that is an Android API rather than a Java API. (I could not find a directly equivalent Java SE library method that is as efficient.)
Related
I have the following java code, which takes three double values (between 0 and 1) of the colors RGB and converts them to decimal format. I understood how the first 8 bit save color x, the second 8 bit color y ... and also how to get the decimal value from the resulting binary. what i dont understand 100% is why we multiply with 255 (i know 128+64+32+16+8+4+2+1). What exactly do we get from multiplying the double value with 255. is it a value which can be stored in 8 bit? And why dont we use 256 (possible amount of one color)?
public final double getR() {
return (1 - cyan);
}
public final double getG() {
return (1 - magenta);
}
public final double getB() {
return (1 - yellow);
}
/**
* Gets the rgb color in one integer.
*
* #return an integer containing the red component in bits 16-23, the green component in bits 8-15
* and the blue component in bits 0-7. Bits 24-32 are zero.
*/
public int getRGB() {
int r = (int) Math.round(getB() * 255);
r |= (int) Math.round(getR() * 255) << 16;
r |= (int) Math.round(getG() * 255) << 8;
return r;
}
Thanks
You need the conversion from double because you cannot store the double value into 8 bit.
Your double values are between 0.0 and 1.0. You can see them as the proportion of color used (e.g. 0.33333333 in yellow means that one-third of the possible yellow is used). As you can see such a double can have many decimal places, which means we need a lot of memory (64-bit) to store such a color.
Your function now tries to store the double value into only 8 bit (256 values). As we said the double value can be seen as a portion (between 0 and 1) and the function calculates the same for 8 bit (between 0 and 255). This can simply be done by multiplying the double value with 255. For the example with yellow (0.33333333 of yellow is used) it is: 0.33333333 * 255 = 84,99999915. The meaning is still the same 84,99999915 yellow parts of 255 yellow parts are used, which is still a third.
In order to get a compressed version of this number, it is rounded to the next integer value. In our example, this is 85, which is really close to the actual portion, but we save a lot of memory.
It makes also sense for the lowest double value 0.0, which is converted to the lowest int value 0. The highest double value 1.0 is converted to 255 (highest 8-bit number).
In conclusion, we convert a double (64-bit) into an only 8-bit number, which has the same proportion of the color, but it is not as accurate.
Edit: As there is also a confusion with the 255: 8 bit can store 256 values (0 to 255). If you can choose 256 as a color value somewhere they use the range 1-256 without 0. Essentially it is the same one shifted by 1.
So I am working on a project where there are 3 sliders(r, g, b) and I use String.format("%02x%02x%02x", r, g, b); to turn it into a hex string, my problem is that I cannot turn it into an int. I have searched the internet and could not find anything, the only one solution was Integer.parseInt(hex, 16) which gives me a value of 87295 and my original color is 0054FF and I get 87295 (the reason I need it as an int is because all of my void methods require a color in a hexadecimal in the form of an int)
Integer.parseInt(String s, 16);
is your friend in need.
Parses the string argument as a signed integer in the radix specified by the second argument... The resulting integer value is returned.
~ Java doc ~
Example:
Integer.parseInt("0054FF", 16);
OUTPUT:
21759
The output does not match your specified output (87295). I believe your error is elsewhere in your code.
EDIT:
According to your comment,
Integer.decode(String s);
is what you need I guess.
My answer assumed you are asking an X - Y problem, which means it may not face to what you need in your question.
Assume r, g, b are of type int, also assume you don't need the Alpha color, then you can use a trick of bit manipulation like this, to directly use the original value to calculate the color value, without turning it into hex string.
int iColor = (r << 16) + (g << 8) + b;
Then this value can be used to turn into hex string for your further need.
String sColorHex = Integer.toHexString(iColor);
Update: Due to the comment of another answer, the alpha should not be ignored, and what the original question really need seems the color int value. Directly use this to get that required value:
int color = 0xFF000000 + (r << 16) + (g << 8) + b;
The original problem doesn't mention about the alpha color, so assume the alpha is 100% (0xFF), which shows as 0xFF000000 (= 0xFF << 24) above.
In my Java application I need to interpret a 32 Bit Fixed Point value. The number format is as follows: The first 15 bits describe the places before the comma/point, the 16th bit represents the sign of the value and the following 16 bits describe the decimal places (1/2,1/4,1/8,1/16,...).
The input is a byte array with four values. The order of the bits in the byte array is little endian.
How can I convert such a number into Java float ?
Just do exactly what it says. Assume x is the 32bit fixed point number as int.
So, put the bits after the point, after the point, and don't use the sign here:
float f = (float)(x & 0x7fff_ffff) / (float)(1 << 16);
Put back the sign:
return x < 0 ? -f : f;
You will lose some precision. A float does not have 31 bits of precision, but your input does. It's easily adapted to doubles though.
Since the sign bit is apparently really in the middle, first get it out:
int sign = x & (1 << 16);
Join the two runs of non-sign bits:
x = (x & 0xFFFF) | ((x >> 1) & 0x7fff0000);
Then do more or less the old thing:
float f = (float)x / (float)(1 << 16);
return sign == 0 ? f : -f;
In case your input is little endian format, use the following approach to generate x:
int x = ByteBuffer.wrap(weirdFixedPoint).order(ByteOrder.LITTLE_ENDIAN).getInt();
where weirdFixedPoint is the byte array containing the 32 bit binary representation.
I have a decimal (not hexadecimal) color code and, using Java, I need to convert it to the three RGB colors.
So for example, 16777215 (pure white) needs to get converted to Red: 255 Green: 255 Blue: 255.
65280 (pure green) needs to get converted to Red: 0 Green 255: Blue: 0 Here is a converter for more examples.
Just doing some small calculations and playing with the calculator on the page linked above, I have determined:
Red equals 65536 (256^2)
(255x65536 = 16711680, aka pure red)
Green equals 256 (256^1)
(255x256 = 65280, aka pure green)
Blue equals 1 (256^0)
(255x1 = 255, aka pure blue)
I can tell it obviously has something to do with bytes, but I am missing that last little bit. I am not the best with the whole concept of bits/bytes/etc and how it interacts with Java, so it is likely fairly simple.
So, anyone know the best way of going about this? What would be the best way to convert a single numerical decimal color into the three separate RGB values using java?
You where telling right: RGB values are encoded as bytes in a int. R is byte 2, G is byte 1 and B is byte 0, summing up to a 24bit color depth. Depending on the endianess, this could be a possible representation.
00000000 00000000 00000000 00000000 <-- 32bit int
^ ^ ^
| | |
+--red here | +--green here
8bit | 8bit
|
+--blue here
8bit
You can extract RGB values with some bit shift and masking:
int red = (color >> 16) & 0xff;
int green = (color >> 8) & 0xff;
int blue = color & 0xff;
You could do
Color color = new Color(16777215);
int red = color.getRed();
int green = color.getGreen();
int blue = color.getBlue();
You can get the channels out by simple bitwise operations.
int r = (color >> 16) & 0xff;
int g = (color >> 8) & 0xff;
int b = color & 0xff;
From there, it should be easy to do whatever you want with the color information.
Decimal, hexadecimal: does not matter. Your computer uses binary representations internally.
You may have noticed that 0xFF00 == 65280.
Decimal and Hexadecimal are user representations.
I know I am a bit late, but...
int r = color / 65536;
int g = (color - r * 65536) / 256;
int b = color - r * 65536 - g * 256;
This is really doing the exact same thing as the binary shifts even though it doesn't use bitwise operators. This also only works when using valid RGB values (meaning each value is an integer between 0 and 255). For efficiency, however, I would use the binary shifts from the above answers.
I know there are N threads for this question but some people are using different and different methods to convert a byte to int. Is this correct what am I writing? Hex to int or hex to decimal? Which one is the correct?
Anyway, why I'm getting 4864 instead of 19 ?
byte[] buffer = ....
buffer[51] = 0x13;
System.out.println( buffer[51] << 8 );
Is this correct what am I writing?
The code you've posted does implicit conversion of int to String, but that will display it in decimal. It's important to understand that a number isn't in either hex or decimal - it's just a number. The same number can be converted to different textual representations, and that's when the base matters. Likewise you can express the same number with different literals, so these two statements are exactly equivalent:
int x = 16;
int x = 0x10;
Anyway, why I'm getting 4864 instead of 19
Because you're explicitly shifting the value left 8 bits:
buffer[51] << 8
That's basically multiplying by 256, and 19 * 256 is 4864.
you are getting 4864 as a result because 4864 is 0x1300 in hex.
if you are expecting 19(0x13) as result then I guess you are trying to do circular shifting.
you can do that using writing like that,
/*hex 0x13 (19 in decimal) is assigned to buffer[51] as int*/
buffer[51] = 0x13;
System.out.println( Integer.rotateRight(buffer[51], 8));