当前位置:编程学习 > wap >>

YUV转RGB 颜色失真问题

最近一直在研究YUV420转RGB565,纠结了N天,转换出来的图片一直是屏幕分成了4块上面两块有明显的红色块,下面两块有明显的绿色块,屏幕颜色失真。求大神指正:代码如下

fis = new FileInputStream(file);
in = new BufferedInputStream(fis);

byte[] buf = new byte[width*heigth*3/2];//视频的宽高乘以1.5 yuv420 一帧数据长度
int size = 0;
while ((size = in.read(buf)) != -1) {
byte[] content = null;
out = new ByteArrayOutputStream();
out.write(buf, 0, size);
content = out.toByteArray();


decodeYUV420SP(rgb,content,width,height);//decodeYUV420SP 在下面
Bitmap bmp = Bitmap.createBitmap(rgb,width, height,

              Bitmap.Config.RGB_565);
       
   

       Matrix matrix = new Matrix(); 
       matrix.postScale(f1,f1); //长和宽放大缩小的比例
                   Bitmap resizeBmp =Bitmap.createBitmap(bmp,0,0,bmp.getWidth(),bmp.getHeight(),matrix,true);
     
      Config.bits[i]=resizeBmp;//存入bitmap数组中 

}
   static void decodeYUV420SP(int[] rgb, byte[] yuv420sp, int width, int height) {

        final int frameSize = width * height;

        for (int j = 0, yp = 0; j < height; j++) {
            int uvp = frameSize + (j >> 1) * width, u = 0, v = 0;
            for (int i = 0; i < width; i++, yp++) {
                int y = (0xff & ((int) yuv420sp[yp])) - 16;
                if (y < 0)
                    y = 0;
                if ((i & 1) == 0) {
                    v = (0xff & yuv420sp[uvp++]) - 128;
                    u = (0xff & yuv420sp[uvp++]) - 128;
                }

                int y1192 = 1192 * y;
                int r = (y1192 + 1634 * v);
                int g = (y1192 - 833 * v - 400 * u);
                int b = (y1192 + 2066 * u);

                if (r < 0)
                    r = 0;
                else if (r > 262143)
                    r = 262143;
                if (g < 0)
                    g = 0;
                else if (g > 262143)
                    g = 262143;
                if (b < 0)
                    b = 0;
                else if (b > 262143)
                    b = 262143;

                rgb[yp] = 0xff000000 | ((r << 6) & 0xff0000) | ((g >> 2) & 0xff00) | ((b >> 10) & 0xff);
            }
        }
    }
--------------------编程问答-------------------- 尝试将

Bitmap bmp = Bitmap.createBitmap(rgb,width, height,

                                  Bitmap.Config.RGB_565);
改为
Bitmap bmp = Bitmap.createBitmap(rgb, 0, width, width, height,
android.graphics.Bitmap.Config.RGB_565);


或者也有可能是你这个rgb值处理不正确,将static void decodeYUV420SP整个方法改一下

static int[] decodeYUV420SP[](byte[] yuv420sp, int width, int height)
{
final int frameSize = width * height;
int rgb[] = new int[frameSize];
for (int j = 0, yp = 0; j < height; j++) {
int uvp = frameSize + (j >> 1) * width, u = 0, v = 0;
for (int i = 0; i < width; i++, yp++) {
int y = (0xff & ((int) yuv420sp[yp])) - 16;
if (y < 0)
y = 0;
if ((i & 1) == 0) {
v = (0xff & yuv420sp[uvp++]) - 128;
u = (0xff & yuv420sp[uvp++]) - 128;
}
int y1192 = 1192 * y;
int r = (y1192 + 1634 * v);
int g = (y1192 - 833 * v - 400 * u);
int b = (y1192 + 2066 * u);
if (r < 0)
r = 0;
else if (r > 262143)
r = 262143;
if (g < 0)
g = 0;
else if (g > 262143)
g = 262143;
if (b < 0)
b = 0;
else if (b > 262143)
b = 262143;
rgb[yp] = 0xff000000 | ((r << 6) & 0xff0000)
| ((g >> 2) & 0xff00) | ((b >> 10) & 0xff);
}
}
return rgb;
}


然后将这一句
decodeYUV420SP(rgb,content,width,height);
改为
int rgb[] = decodeYUV420SP(content,width,height); --------------------编程问答-------------------- 上面decodeYUV420SP的方法代码多加了字符,换成以下的:

static int[] decodeYUV420SP(byte[] yuv420sp, int width, int height)
{
        final int frameSize = width * height;
        int rgb[] = new int[frameSize];
        for (int j = 0, yp = 0; j < height; j++) {
            int uvp = frameSize + (j >> 1) * width, u = 0, v = 0;
            for (int i = 0; i < width; i++, yp++) {
                int y = (0xff & ((int) yuv420sp[yp])) - 16;
                if (y < 0)
                    y = 0;
                if ((i & 1) == 0) {
                    v = (0xff & yuv420sp[uvp++]) - 128;
                    u = (0xff & yuv420sp[uvp++]) - 128;
                }
                int y1192 = 1192 * y;
                int r = (y1192 + 1634 * v);
                int g = (y1192 - 833 * v - 400 * u);
                int b = (y1192 + 2066 * u);
                if (r < 0)
                    r = 0;
                else if (r > 262143)
                    r = 262143;
                if (g < 0)
                    g = 0;
                else if (g > 262143)
                    g = 262143;
                if (b < 0)
                    b = 0;
                else if (b > 262143)
                    b = 262143;
                rgb[yp] = 0xff000000 | ((r << 6) & 0xff0000)
                        | ((g >> 2) & 0xff00) | ((b >> 10) & 0xff);
            }
        }
return rgb;
}

--------------------编程问答--------------------
引用 2 楼  的回复:
上面decodeYUV420SP的方法代码多加了字符,换成以下的:
Java code

static int[] decodeYUV420SP(byte[] yuv420sp, int width, int height)
{
        final int frameSize = width * height;
        int rgb[] = new int[frameSiz……

感谢楼上的作答,我试了你给我的方法,creatbitmap 的时候也改用了您推荐的方法,但是问题还是没有解决,是不是算法某个地方溢出,导致颜色的失真 --------------------编程问答-------------------- v = (0xff & yuv420sp[uvp++]) - 128;//抛java.lang.arrayindexoutofboundsexception异常 --------------------编程问答-------------------- YuvImage yuvImage = new YuvImage(yuv,ImageFormat.NV21, pictureSize.width, pictureSize.height, null); //picturesize 是YUV 是尺寸
ByteArrayOutputStream baos = new ByteArrayOutputStream();
yuvImage.compressToJpeg(new Rect(0,0,pictureSize.width,pictureSize.height), 100, baos);
out = new FileOutputStream(path);
byte[] data = baos.toByteArray();

这个data 是RGB的数据。 可能和你想要的差距比较大
补充:移动开发 ,  Android
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,