我设置了一个 onPreviewFrame 回调。这会得到一个包含 NV21 数据的 byte[]。我已将预览大小设置为 176*144。当设备处于横向模式时,具有 176*144 尺寸的 byte[] 是完美的,但是当设备处于纵向模式时,我仍然会得到具有相同尺寸的 byte[]。
我想将 byte[] 旋转 90 度并获得尺寸为 144*176 的 byte[]。
那么问题来了,如何旋转数据,而不仅仅是预览图呢?Camera.Parameters.setRotation 只影响拍照,不影响视频。Camera.setDisplayOrientation 明确表示它只影响显示预览,而不影响帧字节:
This does not affect the order of byte array passed in
onPreviewFrame(byte[], Camera), JPEG pictures, or recorded videos.
在查看了各种帖子后,我发现这篇文章声明使用 libyuv 的 ConvertToI420。
现在的交易是我已经编译了 libyuv 并且能够调用 libyuv::ConvertToI420 方法,但是我得到的结果 I420 在颜色和显示线条等方面都搞砸了......但是我现在得到的尺寸是144*176,图片可以看这里。
我使用的代码片段如下。
//sourceWidth = 176 and sourceHeight = 144
unsigned char I420M = new unsigned char[(int)(sourceWidth*sourceHeight*1.5)];
unsigned int YSize = sourceWidth * sourceHeight;
// yuvPtr is the NV21 data passed from onPreviewCallback (from JAVA layer)
const uint8* src_frame = const_cast<const uint8*>(yuvPtr);
size_t src_size = YSize;
uint8* pDstY = I420M;
uint8* pDstU = I420M + YSize;
uint8* pDstV = I420M + (YSize/4);
libyuv::RotationMode mode;
if(landscapeLeft){
mode = libyuv::kRotate90;
}else{
mode = libyuv::kRotate270;
}
uint32 format = libyuv::FOURCC_NV21;
int retVal = libyuv::ConvertToI420(src_frame, src_size,
pDstY, sourceHeight,
pDstU, (sourceHeight/2),
pDstV, (sourceHeight/2),
0, 0,
sourceWidth, sourceHeight,
sourceWidth, sourceHeight,
mode,
format);
我不想裁剪图像,只需将其旋转 90(顺时针/逆时针)附加图像用于 kRotate90。
谁能指出我哪里出了问题,我强烈怀疑它是否对传递给 ConvertToI420 方法的参数做一些事情。
任何帮助表示赞赏。