Android convert ImageReader Image to YCbCr_420_SP (NV21) byte array using render script?

前端 未结 1 1209
栀梦
栀梦 2020-12-30 02:48

I am currently working with Javacv which makes use of the public void onPreviewFrame(byte[] data, Camera camera) camera function.

Since camera is deprec

1条回答
  •  时光取名叫无心
    2020-12-30 03:30

    @TargetApi(19)
    public static byte[] yuvImageToByteArray(Image image) {
    
        assert(image.getFormat() == ImageFormat.YUV_420_888);
    
        int width = image.getWidth();
        int height = image.getHeight();
    
        Image.Plane[] planes = image.getPlanes();
        byte[] result = new byte[width * height * 3 / 2];
    
        int stride = planes[0].getRowStride();
        assert (1 == planes[0].getPixelStride());
        if (stride == width) {
            planes[0].getBuffer().get(result, 0, width*height);
        }
        else {
            for (int row = 0; row < height; row++) {
                planes[0].getBuffer().position(row*stride);
                planes[0].getBuffer().get(result, row*width, width);
            }
        }
    
        stride = planes[1].getRowStride();
        assert (stride == planes[2].getRowStride());
        int pixelStride = planes[1].getPixelStride();
        assert (pixelStride == planes[2].getPixelStride());
        byte[] rowBytesCb = new byte[stride];
        byte[] rowBytesCr = new byte[stride];
    
        for (int row = 0; row < height/2; row++) {
            int rowOffset = width*height + width/2 * row;
            planes[1].getBuffer().position(row*stride);
            planes[1].getBuffer().get(rowBytesCb);
            planes[2].getBuffer().position(row*stride);
            planes[2].getBuffer().get(rowBytesCr);
    
            for (int col = 0; col < width/2; col++) {
                result[rowOffset + col*2] = rowBytesCr[col*pixelStride];
                result[rowOffset + col*2 + 1] = rowBytesCb[col*pixelStride];
            }
        }
        return result;
    }
    

    I have published another function with similar requirements. That new implementation tries to take advantage of the fact that quite often, YUV_420_888 is only NV21 in disguise.

    0 讨论(0)
提交回复
热议问题