Android GLSurfaceView 显示YUV数据的坑,图像偏蓝色

前几天学习使用 GLSurfaceView 显示摄像头获取到的YUV数据,发现画面偏蓝色。经过反复的查找,原来是采集的数据排列顺序的问题,
params.setPictureFormat(ImageFormat.NV21);
本来以为数据排列是
Android GLSurfaceView 显示YUV数据的坑,图像偏蓝色_第1张图片
按照这个数据顺序,显示出来的图像有问题(偏蓝色),一个偶然的机会,突然想到是不是UV数据出错了。结果查看了帮助文档:
Android GLSurfaceView 显示YUV数据的坑,图像偏蓝色_第2张图片
居然是 YCrCb,不是 YCbCr哦。
Android GLSurfaceView 显示YUV数据的坑,图像偏蓝色_第3张图片

粗心的人伤不起啊,以后要多加仔细了。

下面放点源代码。
YUV转RGBA像素点算法

这里写代码片 
    private static final String vertexShaderString =
            "attribute vec4 vertexIn;" +
                    "attribute vec2 textureIn;" +
                    "varying vec2 textureOut;" +
                    "void main() {" +
                    "gl_Position = vertexIn;" +
                    "textureOut = textureIn;" +
                    "}";
    private static final String yuvFragmentShaderString =
            "precision mediump float;" +
                    "uniform sampler2D tex_y;" +
                    "uniform sampler2D tex_u;" +
                    "uniform sampler2D tex_v;" +
                    "varying vec2 textureOut;" +
                    "void main() {" +
                    "float y = (texture2D(tex_y, textureOut).r - 16./255.) * 1.164;" +
                    " if(y < 0.0) y=0.0;" +
                    "vec4 c = vec4(y);" +
                    "vec4 U = vec4(texture2D(tex_u, textureOut).r - 128./255.);" +
                    "vec4 V = vec4(texture2D(tex_v, textureOut).r - 128./255.);" +
                    "c += V * vec4(1.596, -0.813, 0, 0);" +
                    "c += U * vec4(0, -0.392, 2.017, 0);" +
//                    "c.a = 1.0;" +
                    "gl_FragColor = c;" +
                    "}";

YUV数据分离

这里写代码片
    @Override
    public void onPreviewFrame(byte[] data, Camera camera) {
        Camera.Size size = camera.getParameters().getPreviewSize(); //获取预览大小
        int width = size.width;
        int height = size.height;
        int pixelLength = width * height;
        byte[] yData = new byte[pixelLength];
        byte[] uData = new byte[pixelLength / 4];
        byte[] vData = new byte[pixelLength / 4];
        System.arraycopy(data, 0, yData, 0, pixelLength);
        for (int i = 0; i < pixelLength / 4; i++) {
            vData[i] = data[pixelLength + i * 2];
            uData[i] = data[pixelLength + i * 2 + 1];
        }
        //处理YUV数据
    }

你可能感兴趣的:(Android GLSurfaceView 显示YUV数据的坑,图像偏蓝色)