1、旋转90度
private byte[] rotateYUV420Degree90(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;
}
2.旋转180度
private static byte[] rotateYUV420Degree180(byte[] data, int imageWidth, int imageHeight) {
byte[] yuv = new byte[imageWidth * imageHeight * 3 / 2];
int i = 0;
int count = 0;
for (i = imageWidth * imageHeight - 1; i >= 0; i--) {
yuv[count] = data[i];
count++;
}
i = imageWidth * imageHeight * 3 / 2 - 1;
for (i = imageWidth * imageHeight * 3 / 2 - 1; i >= imageWidth
* imageHeight; i -= 2) {
yuv[count++] = data[i - 1];
yuv[count++] = data[i];
}
return yuv;
}
3.旋转270度
public static byte[] rotateYUV420Degree270(byte[] data, int imageWidth,
int imageHeight) {
byte[] yuv = new byte[imageWidth * imageHeight * 3 / 2];
int nWidth = 0, nHeight = 0;
int wh = 0;
int uvHeight = 0;
if (imageWidth != nWidth || imageHeight != nHeight) {
nWidth = imageWidth;
nHeight = imageHeight;
wh = imageWidth * imageHeight;
uvHeight = imageHeight >> 1;// uvHeight = height / 2
}
// ??Y
int k = 0;
for (int i = 0; i < imageWidth; i++) {
int nPos = 0;
for (int j = 0; j < imageHeight; j++) {
yuv[k] = data[nPos + i];
k++;
nPos += imageWidth;
}
}
for (int i = 0; i < imageWidth; i += 2) {
int nPos = wh;
for (int j = 0; j < uvHeight; j++) {
yuv[k] = data[nPos + i];
yuv[k + 1] = data[nPos + i + 1];
k += 2;
nPos += imageWidth;
}
}
return rotateYUV420Degree180(yuv, imageWidth, imageHeight);
}
4、左右镜像
//镜像
private void Mirror(byte[] yuv_temp, int w, int h) {
int i, j;
int a, b;
byte temp;
//mirror y
for (i = 0; i < h; i++) {
a = i * w;
b = (i + 1) * w - 1;
while (a < b) {
temp = yuv_temp[a];
yuv_temp[a] = yuv_temp[b];
yuv_temp[b] = temp;
a++;
b--;
}
}
//mirror u
int uindex = w * h;
for (i = 0; i < h / 2; i++) {
a = i * w / 2;
b = (i + 1) * w / 2 - 1;
while (a < b) {
temp = yuv_temp[a + uindex];
yuv_temp[a + uindex] = yuv_temp[b + uindex];
yuv_temp[b + uindex] = temp;
a++;
b--;
}
}
//mirror v
uindex = w * h / 4 * 5;
for (i = 0; i < h / 2; i++) {
a = i * w / 2;
b = (i + 1) * w / 2 - 1;
while (a < b) {
temp = yuv_temp[a + uindex];
yuv_temp[a + uindex] = yuv_temp[b + uindex];
yuv_temp[b + uindex] = temp;
a++;
b--;
}
}
}
//镜像
private void Mirror(byte[] yuv_temp, int w, int h) {
int i, j;
int a, b;
byte temp;
//mirror y
for (i = 0; i < h; i++) {
a = i * w;
b = (i + 1) * w - 1;
while (a < b) {
temp = yuv_temp[a];
yuv_temp[a] = yuv_temp[b];
yuv_temp[b] = temp;
a++;
b--;
}
}
//mirror u
int uindex = w * h;
for (i = 0; i < h / 2; i++) {
a = i * w;
b = (i + 1) * w - 2;
while (a < b) {
temp = yuv_temp[a + uindex];
yuv_temp[a + uindex] = yuv_temp[b + uindex];
yuv_temp[b + uindex] = temp;
a += 2;
b -= 2;
}
}
//mirror v
uindex = w * h;
for (i = 0; i < h / 2; i++) {
a = i * w +1;
b = (i + 1) * w - 1;
while (a < b) {
temp = yuv_temp[a + uindex];
yuv_temp[a + uindex] = yuv_temp[b + uindex];
yuv_temp[b + uindex] = temp;
a += 2;
b -= 2;
}
}
}
注意:以上方法需要在callback的onPreviewFrame()中调用
而且需要把原先
EncoderDebugger debugger = EncoderDebugger.debug(mSettings, mQuality.resX, mQuality.resY);
中参数 mQuality.resX, mQuality.resY调换顺序以防花屏
EncoderDebugger debugger = EncoderDebugger.debug(mSettings, mQuality.resY, mQuality.resX); mPPS =debugger.getB64PPS(); mSPS = debugger.getB64SPS(); mProfilLevel = MP4Parser.toHexString(Base64.decode(mPPS, Base64.NO_WRAP),1,3);
这种方法效果比较合适,直接是转换数据。也查到了转换成jpeg格式,转换图片方向,再转成流传出去,这个方法时进行了压缩,数据减少导致编解码时buffer数组获取数据出问题。
结合OrientationEventListener中的下例方法,进行屏幕方向检测,获取方向,以便方向旋转的判断选择。
@Override
public void onOrientationChanged(int orientation) {
this.Orientation=orientation;
Log.d("OrientationDetector","当前的传感器方向为"+orientation);
if (orientation == ORIENTATION_UNKNOWN) return;
Camera.CameraInfo info =
new Camera.CameraInfo();
Camera.getCameraInfo(0, info);
orientation = (orientation + 45) / 90 * 90;
if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
rotation = (info.orientation - orientation + 360) % 360;
} else { // back-facing camera
rotation = (info.orientation + orientation) % 360;
}
System.out.println("获取相机度数: "+ rotation);
if (camera!=null){
Camera.Parameters parameters = camera.getParameters();
parameters.setRotation(rotation);
camera.setParameters(parameters);
}
}
public int getOrientation(){//对外提供方向0,90,180,270 四个参数
return rotation;
}