[英]Bitmap.setPixels distorts colors under Android
I need to get an image from my phone`s camera. 我需要从手机的相机中获取图像。 I use formula to convert from YUV to RGB.
我使用公式从YUV转换为RGB。 Then I put RGB into IntBuffer.
然后我将RGB放入IntBuffer。 Then I copy pixels from IntBuffer into Bitmap.
然后我将IntBuffer中的像素复制到Bitmap中。 This way gives correct result.
这样可以得到正确的结果。 But I need to use not an IntBuffer but a common array of int[].
但我需要使用的不是IntBuffer,而是一个常见的int []数组。 In this case function bitmap.setPixels produces uncorrect results .
在这种情况下,函数bitmap.setPixels会产生不正确的结果。 Colors are wrong.
颜色是错误的。 The first image is correct.
第一张图片是正确的。 The second image is a result of int[].
第二个图像是int []的结果。
Android 4.1.1 HTC Desire X Android 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++;
}
}
}
this is the simple code i used to swap the red and blue channels when i had a similar issue 这是我遇到类似问题时用于交换红色和蓝色通道的简单代码
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);
}
You can use an int[], then just use IntBuffer.wrap to create an IntBuffer reference without allocating new memory. 您可以使用int [],然后使用IntBuffer.wrap创建IntBuffer引用而不分配新内存。 Bitmap.copyPixelsFromBuffer() copies the raw pixels without modifying them, setPixels is doing alpha multiplication, and possibly format conversion (by all appearances there is some kind of ARGB/BGRA conversion going on.
Bitmap.copyPixelsFromBuffer()复制原始像素而不修改它们,setPixels正在进行alpha乘法,并且可能进行格式转换(所有外观都存在某种ARGB / BGRA转换。
Try these adjustments to continue to use copyPixelsFromBuffer() along with your int[]: 尝试这些调整以继续使用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++;
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.