2011-11-30 83 views
1

我尝试将图像转换为RGB565格式。 我读到这个形象:Java图像转换为RGB565

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

这里是:

picture before convertation

然后我将其转换为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恢复此:

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; 

    } 
} 

我输出这个恢复的图像。但我看到它看起来很差。

enter image description here

我预期失去了图片质量。 但是,正如我想的那样,这张照片必须具有与前一张照片几乎相同的质量。这样对吗? 我的代码是否正确?

+0

我不需要alpha通道。我想获取RGB565图片并将其发送为一串(无符号短)字。微控制器接收该图片并在LCD上显示。我想在LCD上看到几乎像PC上一样的图像。我什么都不懂。我根据所有规则转换图像... –

+0

BufferedImage NewImg = new BufferedImage(CONTROLLER_LCD_WIDTH,CONTROLLER_LCD_HEIGHT,BufferedImage.TYPE_USHORT_565_RGB);我将它更改为BufferedImage.TYPE_INT_ARGB。但没有任何改变...可能是我应该使用另一种方法来进行图片转换。它存在吗? –

回答

1

你看到这些黄色文物的原因是从byteH红色只是由于负值的byteL改写位包含正确的价值观和(部分)绿色渠道。让我解释。记住,如果一个字节中的最高位被设置为1,则该值被认为是负值(-128到-1而不是128到255),并且通过将其转换为int所有额外的高位是设置为1来保存相同的值(-128到-1)。

在您的程序中,当应用OR位运算符|覆盖(饱和)您试图提取的红色和(部分)绿色值时,这些额外位设置为1与byteH中的值直接冲突并显示。

curPixel = (byteH << 8) | (byteL); // BUG: issue with negative byteL values 

解决的办法是应用AND掩码,以确保在应用OR位运算符之前摆脱任何不需要的位。

curPixel = byteL & 0xFF; // Convert byte to int to be within [0 , 255] 
curPixel = (byteH << 8) | curPixel; // Apply OR bit-operator