2011-11-30 139 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