android image 转yuv_分享几个Android摄像头采集的YUV数据旋转与镜像翻转的方法

本文介绍了在Android直播推流中处理Camera采集的YUV数据,包括90度和270度旋转以及前置摄像头的镜像翻转的算法,以适应不同摄像头方向的需求。提供了三个关键算法:rotateYUVDegree90、rotateYUVDegree270和rotateYUVDegree270AndMirror。
摘要由CSDN通过智能技术生成

最近在做直播推流方面的工作,因为需要添加美白,滤镜,AR贴图等效果。所以不能简单的使用SufaceView加Camera的方式进行数据的采集,而是需要对Camera采集到的YUV数据进行相关的处理之后然后再进行推流的操作,YUV数据的返回接口。

@Override

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

}

当然,美白,滤镜,AR贴图等效果采用的是第三方的SDK了。除此之外,因为Android摄像头采集的数据都是有一定的旋转的。一般前置摄像头有270度的旋转,后置摄像头有90的旋转。所以要对YUV数据进行一定旋转操作,同时对于前置摄像头的数据还要进行镜像翻转的操作。网上一般比较多的算法是关于旋转的

private byte[] rotateYUVDegree90(byte[] data, int imageWidth, int imageHeight) {

byte[] yuv = new byte[imageWidth * imageHeight * 3 / 2];

// Rotate the Y luma

int i = 0;

for (int x = 0; x < imageWidth; x++) {

for (int y = imageHeight - 1; y >= 0; y--) {

yuv[i] = data[y * imageWidth + x];

i++;

}

}

// Rotate the U and V color components

i = imageWidth * imageHeight * 3 / 2 - 1;

for (int x = imageWidth - 1; x > 0; x = x - 2) {

for (int y = 0; y < imageHeight / 2; y++) {

yuv[i] = data[(imageWidth * imageHeight) + (y * imageWidth) + x];

i--;

yuv[i] = data[(imageWidth * imageHeight) + (y * imageWidth) + (x - 1)];

i--;

}

}

return yuv;

}

private byte[] rotateYUVDegree270(byte[] data, int imageWidth, int imageHeight) {

byte[] yuv = new byte[imageWidth * imageHeight * 3 / 2];

// Rotate the Y luma

int i = 0;

for (int x = imageWidth - 1; x >= 0; x--) {

for (int y = 0; y < imageHeight; y++) {

yuv[i] = data[y * imageWidth + x];

i++;

}

}// Rotate the U and V color components

i = imageWidth * imageHeight;

for (int x = imageWidth - 1; x > 0; x = x - 2) {

for (int y = 0; y < imageHeight / 2; y++) {

yuv[i] = data[(imageWidth * imageHeight) + (y * imageWidth) + (x - 1)];

i++;

yuv[i] = data[(imageWidth * imageHeight) + (y * imageWidth) + x];

i++;

}

}

return yuv;

}

上述两个算法分别用于90度旋转(后置摄像头)和270度旋转(前置摄像头),但是对于前置摄像头的YUV数据是需要镜像的,参照上面的算法,实现了前置摄像头的镜像算法。

private byte[] rotateYUVDegree270AndMirror(byte[] data, int imageWidth, int imageHeight) {

byte[] yuv = new byte[imageWidth * imageHeight * 3 / 2];

// Rotate and mirror the Y luma

int i = 0;

int maxY = 0;

for (int x = imageWidth - 1; x >= 0; x--) {

maxY = imageWidth * (imageHeight - 1) + x * 2;

for (int y = 0; y < imageHeight; y++) {

yuv[i] = data[maxY - (y * imageWidth + x)];

i++;

}

}

// Rotate and mirror the U and V color components

int uvSize = imageWidth * imageHeight;

i = uvSize;

int maxUV = 0;

for (int x = imageWidth - 1; x > 0; x = x - 2) {

maxUV = imageWidth * (imageHeight / 2 - 1) + x * 2 + uvSize;

for (int y = 0; y < imageHeight / 2; y++) {

yuv[i] = data[maxUV - 2 - (y * imageWidth + x - 1)];

i++;

yuv[i] = data[maxUV - (y * imageWidth + x)];

i++;

}

}

return yuv;

}

至于更多关于YUV和推流的知识,目前我还不是很了解。这篇文章也主要是分享这三个算法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值