Android 自定義相機 Camera 圖片方向問題
阿新 • • 發佈:2018-11-27
相機預覽方向問題
對於相機的預覽方向我們可以通過如下API進行設定
camera.setDisplayOrientation(0);
但是,該API影響的是相機的預覽方向,對於照片的儲存方向並沒有什麼影響,最終照片儲存的方向還是由Camera的影象Sensor決定的。
照片儲存方向問題
第一種解決辦法就是對拍照後的圖片先進行旋轉再進行儲存,如下
但是這種方法比較耗時,尤其圖片較大的時候,不建議使用。public static Bitmap rotateBitmapByDegree(Bitmap bmp, int degree) { if (degree == 0 || null == bmp) return bmp; Bitmap returnBm = null; // 根據旋轉角度,生成旋轉矩陣 Matrix matrix = new Matrix(); matrix.postRotate(degree); // 將原始圖片按照旋轉矩陣進行旋轉,並得到新的圖片 returnBm = Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth(), bmp.getHeight(), matrix, true); if (returnBm == null) { returnBm = bmp; } if (returnBm != bmp && !bmp.isRecycled()) { bmp.recycle(); bmp = null; } return returnBm; }
第二種方法就是通過ExifInterface對圖片進行旋轉,如下
這種方法一定要在儲存完圖片之後再使用,否則不會生效。最終的效果就是你拍照的時候什麼方向,儲存到本地的照片就是什麼方向。public static void setPictureDegreeZero(String path) { try { ExifInterface exifInterface = new ExifInterface(path); // 修正圖片的旋轉角度,設定其不旋轉。這裡也可以設定其旋轉的角度,可以傳值過去, // 例如旋轉90度,傳值ExifInterface.ORIENTATION_ROTATE_90,需要將這個值轉換為String型別的 exifInterface.setAttribute(ExifInterface.TAG_ORIENTATION, String.valueOf(ExifInterface.ORIENTATION_ROTATE_90)) exifInterface.saveAttributes(); } catch (IOException e) { e.printStackTrace(); } }
第三種方法就是通過OrientationEventListener實現對圖片儲存方向的糾正,如下
public class IOrientationEventListener extends OrientationEventListener { public IOrientationEventListener(Context context) { super(context); } @Override public void onOrientationChanged(int orientation) { if (ORIENTATION_UNKNOWN == orientation) { return; } Camera.CameraInfo info = new Camera.CameraInfo(); Camera.getCameraInfo(mCameraId, info); orientation = (orientation + 45) / 90 * 90; int rotation = 0; if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) { rotation = (info.orientation - orientation + 360) % 360; } else { rotation = (info.orientation + orientation) % 360; } Log.e("TAG","orientation: " + orientation); if (null != mCamera) { Camera.Parameters parameters = mCamera.getParameters(); parameters.setRotation(rotation); mCamera.setParameters(parameters); } } }
備註:後置攝像頭cameraId=0;
final IOrientationEventListener orientationEventListener = new IOrientationEventListener(this);
surfaceView.getHolder().setKeepScreenOn(true);//螢幕常亮
surfaceView.getHolder().addCallback(new SurfaceHolder.Callback() {
//當SurfaceHolder被建立的時候回撥
@Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
orientationEventListener.enable();
......
}
//當SurfaceHolder的尺寸發生變化的時候被回撥
@Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {
......
}
//當SurfaceHolder被銷燬的時候回撥
@Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
orientationEventListener.disable();
......
}
});
這種方法最終的效果就是不管你拍照的時候是什麼方向,最終儲存到本地的照片都是0度方向的,跟系統相機拍照後一個效果。