Camera中onPreviewFrame()方法的视频方向旋转

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);
}
注意:以上方法需要在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;
}


你可能感兴趣的:(Andriod)