android camera显示偏移,Android Camera开发系列:调整Camera预览方向

有时候我们想根据自己的需要调整下Camera的预览方向,那么是调用哪个API可以达到我们的目的呢?

我们看下下图拍的几张小可爱的照片,分别是正常方向、旋转180度、90度拍的照片。

18903b9cfff717e3109faf925f98741b.png

e953276998948fd236e81764aa001d44.png

107c8d3b1a10fd35086dd37e2a67cfe3.png

一、Camera API

Camera1上,我们可以通过**setDisplayOrientation(int degress);**来设置camera预览的方向。mCamera.setDisplayOrientation(Surface.ROTATION_180);复制代码

这里也贴下源码里面关于setDisplayOrientaion接口的详细说明。/**

* Set the clockwise rotation of preview display in degrees. This affects

* the preview frames and the picture displayed after snapshot. This method

* is useful for portrait mode applications. Note that preview display of

* front-facing cameras is flipped horizontally before the rotation, that

* is, the image is reflected along the central vertical axis of the camera

* sensor. So the users can see themselves as looking into a mirror.

*

This does not affect the order of byte array passed in {@link

* PreviewCallback#onPreviewFrame}, JPEG pictures, or recorded videos. This

* method is not allowed to be called during preview.

*

If you want to make the camera image show in the same orientation as

* the display, you can use the following code.

 
 

* public static void setCameraDisplayOrientation(Activity activity,

*         int cameraId, android.hardware.Camera camera) {

*     android.hardware.Camera.CameraInfo info =

*             new android.hardware.Camera.CameraInfo();

*     android.hardware.Camera.getCameraInfo(cameraId, info);

*     int rotation = activity.getWindowManager().getDefaultDisplay()

*             .getRotation();

*     int degrees = 0;

*     switch (rotation) {

*         case Surface.ROTATION_0: degrees = 0; break;

*         case Surface.ROTATION_90: degrees = 90; break;

*         case Surface.ROTATION_180: degrees = 180; break;

*         case Surface.ROTATION_270: degrees = 270; break;

*     }

*

*     int result;

*     if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {

*         result = (info.orientation + degrees) % 360;

*         result = (360 - result) % 360;  // compensate the mirror

*     } else {  // back-facing

*         result = (info.orientation - degrees + 360) % 360;

*     }

*     camera.setDisplayOrientation(result);

* }

*

Starting from API level 14, this method can be called when preview is

* active.

*

Note: Before API level 24, the default value for orientation is 0\. Starting in

* API level 24, the default orientation will be such that applications in forced-landscape mode

* will have correct preview orientation, which may be either a default of 0 or

* 180\. Applications that operate in portrait mode or allow for changing orientation must still

* call this method after each orientation change to ensure correct preview display in all

* cases.

*

* @param degrees the angle that the picture will be rotated clockwise.

*                Valid values are 0, 90, 180, and 270.

* @throws RuntimeException if setting orientation fails; usually this would

*    be because of a hardware or other low-level error, or because

*    release() has been called on this Camera instance.

* @see #setPreviewDisplay(SurfaceHolder)

*/

public native final void setDisplayOrientation(int degrees);复制代码

二、Camera2 API

Camera2的API上,找了一通,发现并没有像Camera1上,可以通过类似的接口来设置预览方向,不过可以通过TextureView.setTransform(matrix);来通过调整textureView的显示来达到目的。public void openCamera(){

CameraManager manager = (CameraManager) mContext.getSystemService(Context.CAMERA_SERVICE);

try {

......

//调整预览画面显示方向

configureTextureViewTransform(mTextureView.getWidth(),mTextureView.getHeight());

manager.openCamera(cameraId, mStateCallback, null);

......

}

}

private void configureTextureViewTransform(int viewWidth, int viewHeight) {

if (null == mTextureView) {

return;

}

int rotation = 0 ;/*activity.getWindowManager().getDefaultDisplay().getRotation();*/

Matrix matrix = new Matrix();

RectF viewRect = new RectF(0, 0, viewWidth, viewHeight);

RectF bufferRect = new RectF(0, 0, mPreviewSize.getHeight(), mPreviewSize.getWidth());

float centerX = viewRect.centerX();

float centerY = viewRect.centerY();

if (Surface.ROTATION_90 == rotation || Surface.ROTATION_270 == rotation) {

bufferRect.offset(centerX - bufferRect.centerX(), centerY - bufferRect.centerY());

matrix.setRectToRect(viewRect, bufferRect, Matrix.ScaleToFit.FILL);

float scale = Math.max(

(float) viewHeight / mPreviewSize.getHeight(),

(float) viewWidth / mPreviewSize.getWidth());

matrix.postScale(scale, scale, centerX, centerY);

matrix.postRotate(90 * (rotation - 2), centerX, centerY);

}else if (Surface.ROTATION_180 == rotation) {

matrix.postRotate(180, centerX, centerY);

}

mTextureView.setTransform(matrix);

}复制代码

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值