有時候我們想根據(jù)自己的需要調(diào)整下Camera的預覽方向,那么是調(diào)用哪個API可以達到我們的目的呢迷殿?
我們看下下圖拍的幾張小可愛的照片乱顾,分別是正常方向、旋轉(zhuǎn)180度绪妹、90度拍的照片晚碾。
正常方向
旋轉(zhuǎn)180度
旋轉(zhuǎn)90度
一、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.
*
* <p>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.
*
* <p>If you want to make the camera image show in the same orientation as
* the display, you can use the following code.
* <pre>
* 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);
* }
* </pre>
*
* <p>Starting from API level 14, this method can be called when preview is
* active.
*
* <p><b>Note: </b>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.</p>
*
* @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上,找了一通狡孔,發(fā)現(xiàn)并沒有像Camera1上懂诗,可以通過類似的接口來設置預覽方向,不過可以通過TextureView.setTransform(matrix);來通過調(diào)整textureView的顯示來達到目的苗膝。
public void openCamera(){
CameraManager manager = (CameraManager) mContext.getSystemService(Context.CAMERA_SERVICE);
try {
......
//調(diào)整預覽畫面顯示方向
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);
}