【问题标题】:Create / Use YUV Image buffer from Camera Preview class从 Camera Preview 类创建/使用 YUV 图像缓冲区
【发布时间】:2011-12-14 16:38:10
【问题描述】:

在我们的应用程序中,我们需要使用来自相机 @ 33 fps 的捕获帧并将其传递给压缩,然后再将其发送到服务器,

我的压缩模块可以取YUV图片,对图片进行压缩,我的相机配置如下,

宽度 = 500 像素,
高度 = 300 像素,
图片格式:YV12

关于预览回调

camera.setPreviewCallback(new PreviewCallback() {

                public void onPreviewFrame(byte[] data, Camera arg1) {

                                }
}

数据大小是 230400,但我想它会在

500*300(Y) + 500*300/4(U) + 500*300/4(V) 即 2250000

即多了 5400 字节,这是否意味着,我可以忽略扩孔?

我还需要创建 YUVImage 对象,但步幅信息没有出现,所以我们如何从上述数据创建 YUVImage。

真诚感谢您的阅读,如果有人可以帮助我,我真的很感激。

【问题讨论】:

    标签: java android camera yuv


    【解决方案1】:

    无法帮助解决数据大小问题,但要从相机预览中获取 YUV,您有 2 个选择。如果运行 Android 2.2 或更高版本,您可以使用 android.graphics.YuvImage 类,只需从 PreviewCallback 将您的 bytearray 传递给它的构造函数。

    如果您需要支持 pre 2.2,那么您需要执行以下操作:

    /**
     * Decodes YUV frame to a buffer which can be use to create a bitmap.
     * use this for OS < FROYO which has a native YUV decoder
     * decode Y, U, and V values on the YUV 420 buffer described as YCbCr_422_SP by Android 
     * @param rgb the outgoing array of RGB bytes
     * @param fg the incoming frame bytes
     * @param width of source frame
     * @param height of source frame
     * @throws NullPointerException
     * @throws IllegalArgumentException
     */
    private static void decodeYUV_impl(int[] rgb, byte[] fg, int width, int height) throws NullPointerException, IllegalArgumentException 
    {
        int sz = width * height;
        if (rgb == null)
            throw new NullPointerException("buffer out is null");
        if (rgb.length < sz)
            throw new IllegalArgumentException("buffer out size " + rgb.length
                    + " < minimum " + sz);
        if (fg == null)
            throw new NullPointerException("buffer 'fg' is null");
    
        if (fg.length < sz)
            throw new IllegalArgumentException("buffer fg size " + fg.length
                    + " < minimum " + sz * 3 / 2);
    
        int i, j;
        int Y, Cr = 0, Cb = 0;
        for (j = 0; j < height; j++) {
            int pixPtr = j * width;
            final int jDiv2 = j >> 1;
        for (i = 0; i < width; i++) {
            Y = fg[pixPtr];
            if (Y < 0)
                Y += 255;
            if ((i & 0x1) != 1) {
                final int cOff = sz + jDiv2 * width + (i >> 1) * 2;
                Cb = fg[cOff];
                if (Cb < 0)
                    Cb += 127;
                else
                    Cb -= 128;
                Cr = fg[cOff + 1];
                if (Cr < 0)
                    Cr += 127;
                else
                    Cr -= 128;
            }
            int R = Y + Cr + (Cr >> 2) + (Cr >> 3) + (Cr >> 5);
            if (R < 0)
                R = 0;
            else if (R > 255)
                R = 255;
            int G = Y - (Cb >> 2) + (Cb >> 4) + (Cb >> 5) - (Cr >> 1)
                    + (Cr >> 3) + (Cr >> 4) + (Cr >> 5);
            if (G < 0)
                G = 0;
            else if (G > 255)
                G = 255;
            int B = Y + Cb + (Cb >> 1) + (Cb >> 2) + (Cb >> 6);
            if (B < 0)
                B = 0;
            else if (B > 255)
                B = 255;
            rgb[pixPtr++] = (0xff000000 + (B << 16) + (G << 8) + R);
        }
        }
    
    }
    

    【讨论】:

    • 谢谢,实际上,我只需要将 YUV 数据提供给我的编码器 libvpx,现在我有 YUV 数据,所以不想将其转换为 RGB
    猜你喜欢
    • 2019-02-08
    • 2021-11-29
    • 2016-10-23
    • 2019-09-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多