Android如何修复相机的方向

在这里输入图像说明

注意摄像头的视图(不是被捕获的图像)被翻转到左边(上面的图像), Activity方向是正确的,但是摄像机视图被搞乱了,请帮助我们:)谢谢。

这里是xml文件:

 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center|top" android:orientation="vertical" > <SurfaceView android:id="@+id/camerapreview" android:layout_margin="10dp" android:layout_width="300dp" android:layout_height="300dp" /> </LinearLayout> </LinearLayout> </LinearLayout> 

这里是java代码:

 public class CustomCameraActivity extends Activity implements SurfaceHolder.Callback { Camera camera; SurfaceView surfaceView; SurfaceHolder surfaceHolder; boolean previewing = false; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.camera); surfaceView = (SurfaceView)findViewById(R.id.camerapreview); surfaceHolder = surfaceView.getHolder(); surfaceHolder.addCallback(this); } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { if(previewing){ camera.stopPreview(); previewing = false; } if (camera != null){ try { camera.setPreviewDisplay(surfaceHolder); camera.startPreview(); previewing = true; } catch (IOException e) { e.printStackTrace(); } } } @Override public void surfaceCreated(SurfaceHolder holder) { camera = Camera.open(); } @Override public void surfaceDestroyed(SurfaceHolder holder) { camera.stopPreview(); camera.release(); camera = null; previewing = false; } } 

我在这里find了解决scheme。 通过@Ed Jellard回答。

我只需要添加camera.setDisplayOrientation(90);surfaceCreated(SurfaceHolder holder)方法,现在显示在正确的angular度。

在这里输入图像说明

看到快乐的T-REX 🙂

这个问题很久以前就解决了,但是我遇到了一些困难,把所有的东西拼在一起,所以这里是我的最终解决scheme,我希望这能帮助其他人:

 public void startPreview() { try { Log.i(TAG, "starting preview: " + started); // .... Camera.CameraInfo camInfo = new Camera.CameraInfo(); Camera.getCameraInfo(cameraIndex, camInfo); int cameraRotationOffset = camInfo.orientation; // ... Camera.Parameters parameters = camera.getParameters(); List<Camera.Size> previewSizes = parameters.getSupportedPreviewSizes(); Camera.Size previewSize = null; float closestRatio = Float.MAX_VALUE; int targetPreviewWidth = isLandscape() ? getWidth() : getHeight(); int targetPreviewHeight = isLandscape() ? getHeight() : getWidth(); float targetRatio = targetPreviewWidth / (float) targetPreviewHeight; Log.v(TAG, "target size: " + targetPreviewWidth + " / " + targetPreviewHeight + " ratio:" + targetRatio); for (Camera.Size candidateSize : previewSizes) { float whRatio = candidateSize.width / (float) candidateSize.height; if (previewSize == null || Math.abs(targetRatio - whRatio) < Math.abs(targetRatio - closestRatio)) { closestRatio = whRatio; previewSize = candidateSize; } } int rotation = getWindowManager().getDefaultDisplay().getRotation(); int degrees = 0; switch (rotation) { case Surface.ROTATION_0: degrees = 0; break; // Natural orientation case Surface.ROTATION_90: degrees = 90; break; // Landscape left case Surface.ROTATION_180: degrees = 180; break;// Upside down case Surface.ROTATION_270: degrees = 270; break;// Landscape right } int displayRotation; if (isFrontFacingCam) { displayRotation = (cameraRotationOffset + degrees) % 360; displayRotation = (360 - displayRotation) % 360; // compensate // the // mirror } else { // back-facing displayRotation = (cameraRotationOffset - degrees + 360) % 360; } Log.v(TAG, "rotation cam / phone = displayRotation: " + cameraRotationOffset + " / " + degrees + " = " + displayRotation); this.camera.setDisplayOrientation(displayRotation); int rotate; if (isFrontFacingCam) { rotate = (360 + cameraRotationOffset + degrees) % 360; } else { rotate = (360 + cameraRotationOffset - degrees) % 360; } Log.v(TAG, "screenshot rotation: " + cameraRotationOffset + " / " + degrees + " = " + rotate); Log.v(TAG, "preview size: " + previewSize.width + " / " + previewSize.height); parameters.setPreviewSize(previewSize.width, previewSize.height); parameters.setRotation(rotate); camera.setParameters(parameters); camera.setPreviewDisplay(mHolder); camera.startPreview(); Log.d(TAG, "preview started"); started = true; } catch (IOException e) { Log.d(TAG, "Error setting camera preview: " + e.getMessage()); } } 

Camera.CameraInfo类中有一个属性,名称为orientation 。 它返回整数。 你可以得到当前的方向,然后相应地改变。

看到这个答案处理方向和CameraInfo类。

我相信这会帮助你。

当您旋转手机时,相机会自动旋转,但是如果您希望相机或相框捕捉的图像处于正确的方向,请使用以下方法: –

 public void rotate(String filePath){ Bitmap cameraBitmap = null; BitmapFactory.Options bmOptions = new BitmapFactory.Options(); bmOptions.inJustDecodeBounds = false; bmOptions.inPurgeable = true; bmOptions.inBitmap = cameraBitmap; bmOptions.inMutable = true; cameraBitmap = BitmapFactory.decodeFile(filePath,bmOptions); // Your image file path ByteArrayOutputStream bos = new ByteArrayOutputStream(); cameraBitmap.compress(Bitmap.CompressFormat.JPEG, 100, bos); ExifInterface exif = new ExifInterface(filePath); float rotation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL); System.out.println(rotation); float rotationInDegrees = exifToDegrees(rotation); System.out.println(rotationInDegrees); Matrix matrix = new Matrix(); matrix.postRotate(rotationInDegrees); Bitmap rotatedBitmap = Bitmap.createBitmap(cameraBitmap , 0, 0, cameraBitmap.getWidth(), cameraBitmap.getHeight(), matrix, true); FileOutputStream fos=new FileOutputStream(filePath); rotatedBitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos); fos.write(bos.toByteArray()); cameraBitmap.recycle(); System.gc(); fos.flush(); fos.close(); } private static float exifToDegrees(float exifOrientation) { if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_90) { return 90; } else if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_180) { return 180; } else if (exifOrientation == ExifInterface.ORIENTATION_ROTATE_270) { return 270; } return 0; }