Java图像转换为RGB565 [英] Java image conversion to RGB565

查看:935
本文介绍了Java图像转换为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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆