在图像读取器中将帧从YUV_420_888格式错误地转换为NV21

问题描述:

我配置了我的代码,以便使用imageReader对象和其他众所周知的camera2 API从我的设备的相机获取YUV_420_888帧流。现在我需要将这些帧转换为NV21像素格式,并调用一个本机函数,期望此格式的帧执行某些计算。这是我使用的ImageReader回调中重新排列帧的字节数的代码:在图像读取器中将帧从YUV_420_888格式错误地转换为NV21

 ImageReader.OnImageAvailableListener readerListener = new ImageReader.OnImageAvailableListener() { 
      @Override 
      public void onImageAvailable(ImageReader mReader) { 
       Image image = null; 
       image = mReader.acquireLatestImage(); 
       if (image == null) { 
        return; 
       }       

       byte[] bytes = convertYUV420ToNV21(image); 

       nativeVideoFrame(bytes); 
       image.close(); 
      } 
     }; 

private byte[] convertYUV420ToNV21(Image imgYUV420) { 

    byte[] rez; 

    ByteBuffer buffer0 = imgYUV420.getPlanes()[0].getBuffer(); 
    ByteBuffer buffer1 = imgYUV420.getPlanes()[1].getBuffer(); 
    ByteBuffer buffer2 = imgYUV420.getPlanes()[2].getBuffer(); 

    int buffer0_size = buffer0.remaining(); 
    int buffer1_size = buffer1.remaining(); 
    int buffer2_size = buffer2.remaining(); 

    byte[] buffer0_byte = new byte[buffer0_size]; 
    byte[] buffer1_byte = new byte[buffer1_size]; 
    byte[] buffer2_byte = new byte[buffer2_size]; 
    buffer0.get(buffer0_byte, 0, buffer0_size); 
    buffer1.get(buffer1_byte, 0, buffer1_size); 
    buffer2.get(buffer2_byte, 0, buffer2_size); 


    ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); 
    try { 
     outputStream.write(buffer0_byte); 
     outputStream.write(buffer1_byte); 
     outputStream.write(buffer2_byte); 
    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 

    rez = outputStream.toByteArray(); 

    return rez; 
} 

但我不知道为什么,得到的帧在水平方向“翻转”。换句话说,当我将相机移动到右侧时,我描述的包装过程之后的框架向左移动,就像传感器放置在反自然位置一样。

我希望你可以明白我的意思

感谢,

JM

+1

在'convertYUV420ToNV21'和'compressToJpeg'之后交换蓝色和红色的颜色。 –

+0

@VladimirKulyk在写入输出流时,重新命令为0/2/1来取消交换蓝色和红色 – AngeloS

这是确定的相机产生镜像图像。如果你不希望它被镜像 - 你需要执行水平镜像,交换每一行中的像素。

+0

您节省了我的一天。这是我正在寻找的暗示 – user3417052