0

我需要从手机的相机中获取图像。我使用公式将 YUV 转换为 RGB。然后我将 RGB 放入 IntBuffer。然后我将像素从 IntBuffer 复制到位图中。这种方式给出了正确的结果。但是我需要使用的不是 IntBuffer,而是一个通用的 int[] 数组。在这种情况下,函数 bitmap.setPixels 会产生不正确的结果。颜色不对。第一张图是对的。第二个图像是 int[] 的结果。

安卓 4.1.1 HTC Desire X

在此处输入图像描述 在此处输入图像描述

    @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++;
         }
     }               
}
4

2 回答 2

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);
} 
于 2013-11-04T17:00:30.527 回答
0

您可以使用 int[],然后只需使用 IntBuffer.wrap 创建 IntBuffer 引用而不分配新内存。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++;
         }
     }               
}
于 2013-11-04T17:39:53.260 回答