2013-11-04 60 views
0

我需要從手機的相機中獲取圖像。我使用公式將YUV轉換爲RGB。然後我把RGB放入IntBuffer。然後我將IntBuffer中的像素複製到位圖中。這樣可以給出正確的結果。 但我需要使用不是一個IntBuffer,而是一個普通的int []數組。在這種情況下,函數bitmap.setPixels產生不正確的結果。顏色是錯誤的。 第一張圖片是正確的。第二個圖像是int []的結果。Bitmap.setPixels在Android下扭曲顏色

的Android 4.1.1 的HTC Desire X

enter image description here enter image description here

@Override 
public void onPreviewFrame(byte[] data, Camera camera) { 
    Size previewSize = parameters.getPreviewSize(); 
    int imageWidth = previewSize.width; 
    int imageHeight = previewSize.height; 

    if(toggleButton1.isChecked()) 
    { 
     if(ck==0) 
     { 

       Bitmap preview_bitmap = Bitmap.createBitmap(imageWidth, imageHeight, Bitmap.Config.ARGB_8888); 
       Bitmap preview_bitmap2 = Bitmap.createBitmap(imageWidth, imageHeight, Bitmap.Config.ARGB_8888); 

      final byte alpha = (byte) 255; 
      int numPixels = imageWidth*imageHeight; 

      IntBuffer intBuffer = IntBuffer.allocate(imageWidth*imageHeight); 
      intBuffer.position(0); 

      int buff[]= new int[imageWidth*imageHeight]; 

      int i=0; 
      for (int y = 0; y < imageHeight; y++) {  
       for (int x = 0; x < imageWidth; x++) { 
        int Y = data[y*imageWidth + x] & 0xff; 

        int xby2 = x/2; 
        int yby2 = y/2; 
        float U = (float)(data[numPixels + 2*xby2 + yby2*imageWidth] & 0xff) - 128.0f; 
        float V = (float)(data[numPixels + 2*xby2 + 1 + yby2*imageWidth] & 0xff) - 128.0f; 
        // Do the YUV -> RGB conversion 
        float Yf = 1.164f*((float)Y) - 16.0f; 
        int R = (int)(Yf + 1.596f*V); 
        int G = (int)(Yf - 0.813f*V - 0.391f*U); 
        int B = (int)(Yf   + 2.018f*U); 

        R = R < 0 ? 0 : R > 255 ? 255 : R; 
        G = G < 0 ? 0 : G > 255 ? 255 : G; 
        B = B < 0 ? 0 : B > 255 ? 255 : B; 


        intBuffer.put(alpha*16777216 + R*65536 + G*256 + B); 
        buff[i]=  (alpha*16777216 + R*65536 + G*256 + B); 


        i++;  
       } 
      } 

      intBuffer.flip(); 

      preview_bitmap.copyPixelsFromBuffer(intBuffer); 
      preview_bitmap2.setPixels(buff,0,imageWidth,0,0,imageWidth,imageHeight); 

      //imageView1.setImageBitmap(preview_bitmap); 
      //imageView2.setImageBitmap(preview_bitmap2); 

      save_SDcard(preview_bitmap,"pic1.jpg"); 
      save_SDcard(preview_bitmap2,"pic2.jpg"); 
      ck++; 
     } 
    }    
} 

回答

2

這是一個簡單的代碼我用來交換的紅色和藍色通道的時候我也有類似的問題

for (int i = 0; i < totalPixels; ++i) { 
    // The alpha and green channels' positions are preserved while the red and blue are swapped 
    pixelsBuffer[i] = ((pixelsBuffer[i] & 0xff00ff00)) | ((pixelsBuffer[i] & 0x000000ff) << 16) | ((pixelsBuffer[i] & 0x00ff0000) >> 16); 
} 
0

您可以使用int [],然後使用IntBuffer.wrap創建一個IntBuffer引用w沒有分配新的內存。 Bitmap.copyPixelsFromBuffer()複製原始像素而不修改它們,setPixels正在進行alpha乘法,並可能進行格式轉換(所有外觀都有某種ARGB/BGRA轉換正在進行。

嘗試這些調整以繼續使用copyPixelsFromBuffer()以及你的int []:

@Override 
public void onPreviewFrame(byte[] data, Camera camera) { 
    Size previewSize = parameters.getPreviewSize(); 
    int imageWidth = previewSize.width; 
    int imageHeight = previewSize.height; 

    if(toggleButton1.isChecked()) 
    { 
     if(ck==0) 
     { 

       Bitmap preview_bitmap = Bitmap.createBitmap(imageWidth, imageHeight, Bitmap.Config.ARGB_8888); 
       Bitmap preview_bitmap2 = Bitmap.createBitmap(imageWidth, imageHeight, Bitmap.Config.ARGB_8888); 

      final byte alpha = (byte) 255; 
      int numPixels = imageWidth*imageHeight; 
      int buff[]= new int[numPixels]; 

      int i=0; 
      for (int y = 0; y < imageHeight; y++) {  
       for (int x = 0; x < imageWidth; x++) { 
        int Y = data[y*imageWidth + x] & 0xff; 

        int xby2 = x/2; 
        int yby2 = y/2; 
        float U = (float)(data[numPixels + 2*xby2 + yby2*imageWidth] & 0xff) - 128.0f; 
        float V = (float)(data[numPixels + 2*xby2 + 1 + yby2*imageWidth] & 0xff) - 128.0f; 
        // Do the YUV -> RGB conversion 
        float Yf = 1.164f*((float)Y) - 16.0f; 
        int R = (int)(Yf + 1.596f*V); 
        int G = (int)(Yf - 0.813f*V - 0.391f*U); 
        int B = (int)(Yf   + 2.018f*U); 

        R = R < 0 ? 0 : R > 255 ? 255 : R; 
        G = G < 0 ? 0 : G > 255 ? 255 : G; 
        B = B < 0 ? 0 : B > 255 ? 255 : B; 

        // better implementation than multiplying 
        buff[i] = Color.argb(alpha,R,G,B); 
        i++;  
       } 
      } 

      // just wrap your buff 
      IntBuffer intBuffer = IntBuffer.wrap(buff); 

      preview_bitmap.copyPixelsFromBuffer(intBuffer); 
      preview_bitmap2.setPixels(buff,0,imageWidth,0,0,imageWidth,imageHeight); 

      //imageView1.setImageBitmap(preview_bitmap); 
      //imageView2.setImageBitmap(preview_bitmap2); 

      save_SDcard(preview_bitmap,"pic1.jpg"); 
      save_SDcard(preview_bitmap2,"pic2.jpg"); 
      ck++; 
     } 
    }    
}