Java图像转换为RGB565 [英] Java image conversion to RGB565
问题描述
我尝试将图像转换为RGB565格式。
我读过这张图片:
I try to convert image to RGB565 format. I read this image:
BufferedImage bufImg = ImageIO.read(imagePathFile);
sendImg = new BufferedImage(CONTROLLER_LCD_WIDTH/*320*/, CONTROLLER_LCD_HEIGHT/*240*/, BufferedImage.TYPE_USHORT_565_RGB);
sendImg.getGraphics().drawImage(bufImg, 0, 0, CONTROLLER_LCD_WIDTH/*320*/, CONTROLLER_LCD_HEIGHT/*240*/, null);
以下是:
然后我将其转换为RGB565:
Then I convert it to RGB565:
int numByte=0;
byte[] OutputImageArray = new byte[CONTROLLER_LCD_WIDTH*CONTROLLER_LCD_HEIGHT*2];
int i=0;
int j=0;
int len = OutputImageArray.length;
for (i=0;i<CONTROLLER_LCD_WIDTH;i++) {
for (j=0;j<CONTROLLER_LCD_HEIGHT;j++) {
Color c = new Color(sendImg.getRGB(i, j));
int aRGBpix = sendImg.getRGB(i, j);
int alpha;
int red = c.getRed();
int green = c.getGreen();
int blue = c.getBlue();
//RGB888
red = (aRGBpix >> 16) & 0x0FF;
green = (aRGBpix >> 8) & 0x0FF;
blue = (aRGBpix >> 0) & 0x0FF;
alpha = (aRGBpix >> 24) & 0x0FF;
//RGB565
red = red >> 3;
green = green >> 2;
blue = blue >> 3;
//A pixel is represented by a 4-byte (32 bit) integer, like so:
//00000000 00000000 00000000 11111111
//^ Alpha ^Red ^Green ^Blue
//Converting to RGB565
short pixel_to_send = 0;
int pixel_to_send_int = 0;
pixel_to_send_int = (red << 11) | (green << 5) | (blue);
pixel_to_send = (short) pixel_to_send_int;
//dividing into bytes
byte byteH=(byte)((pixel_to_send >> 8) & 0x0FF);
byte byteL=(byte)(pixel_to_send & 0x0FF);
//Writing it to array - High-byte is second
OutputImageArray[numByte]=byteH;
OutputImageArray[numByte+1]=byteL;
numByte+=2;
}
}
然后我尝试从结果数组中恢复此 OutputImageArray
:
Then I try to restore this from resulting array OutputImageArray
:
i=0;
j=0;
numByte=0;
BufferedImage NewImg = new BufferedImage(CONTROLLER_LCD_WIDTH, CONTROLLER_LCD_HEIGHT, BufferedImage.TYPE_USHORT_565_RGB);
for (i=0;i<CONTROLLER_LCD_WIDTH;i++) {
for (j=0;j<CONTROLLER_LCD_HEIGHT;j++) {
int curPixel=0;
int alpha=0x0FF;
int red;
int green;
int blue;
byte byteL=0;
byte byteH=0;
byteH = OutputImageArray[numByte];
byteL = OutputImageArray[numByte+1];
curPixel= (byteH << 8) | (byteL);
//RGB565
red = (curPixel >> (6+5)) & 0x01F;
green = (curPixel >> 5) & 0x03F;
blue = (curPixel) & 0x01F;
//RGB888
red = red << 3;
green = green << 2;
blue = blue << 3;
//aRGB
curPixel = 0;
curPixel = (alpha << 24) | (red << 16) | (green << 8) | (blue);
NewImg.setRGB(i, j, curPixel);
numByte+=2;
}
}
我输出此恢复的图像。但我发现它看起来很糟糕。
I output this restored image. But I see that it looks very poor.
我预计图片质量会丢失。
但是正如我想的那样,这张照片必须具有与前一张照片几乎相同的质量。这样对吗?
我的代码是对的吗?
I expected the lost of pictures quality. But as I thought, this picture has to have almost the same quality as the previous picture. Is it right? Is my code right?
推荐答案
您看到这些黄色文物的原因仅仅是由于<$的负值c $ c> byteL 从 byteH
覆盖包含红色和(部分)的正确值的位绿色频道。让我解释一下。
The reason you see these yellow artefacts is simply due to negative values for byteL
overwriting bits from byteH
containing the correct values for red and (part of) green channels. Let me explain.
请记住,如果一个字节中的最高位设置为1,则该值被视为负数(-128到-1而不是128到255) ,并将其转换为 int
,所有额外的高位都设置为1以保存相同的值(-128到-1)。
Remember, if the highest bit in a byte is set to 1, the value is considered negative (-128 to -1 instead of 128 to 255), and by converting it to an int
all the extra high-bits are set to 1 to conserve the same values (-128 to -1).
在程序中,当应用OR位运算符<$时,设置为1的这些额外位与 byteH
中的值直接冲突。 c $ c> | ,覆盖(饱和)您尝试提取和显示的红色和(部分)绿色值。
In your program, these extra bits set to 1 are in direct conflict with the value in byteH
when applying the OR bit-operator |
, overwriting (saturating) the red and (part of) green values you are trying to extract and display.
curPixel = (byteH << 8) | (byteL); // BUG: issue with negative byteL values
解决方法是应用AND掩码以确保在应用OR位运算符之前去除任何不需要的位。
A solution is to apply an AND-mask to be sure to get rid of any unwanted bits before applying the OR bit-operator.
curPixel = byteL & 0xFF; // Convert byte to int to be within [0 , 255]
curPixel = (byteH << 8) | curPixel; // Apply OR bit-operator
这篇关于Java图像转换为RGB565的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!