Android相机开发中遇到的坑(注意事项)
2017-06-08 17:52
211 查看
Android相机开发中遇到的坑(注意事项)
相机预览界面方向的设定
在默认情况下有些相机用户看到的预览界面和真实世界的情况是颠倒的,所以我们需要设定预览界面的方向,如下所示:public static int getDisplayRotation(Activity activity) { int rotation = activity.getWindowManager().getDefaultDisplay().getRotation(); switch (rotation) { case Surface.ROTATION_0: return 0; case Surface.ROTATION_90: return 90; case Surface.ROTATION_180: return 180; case Surface.ROTATION_270: return 270; } return 0; }
public static int getDisplayOrientation(int degrees, int cameraId) { // See android.hardware.Camera.setDisplayOrientation for // documentation. Camera.CameraInfo info = new Camera.CameraInfo(); Camera.getCameraInfo(cameraId, info); 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; } return result; }
最后设定预览界面的方向
mDisplayRotation = CameraUtils.getDisplayRotation(mActivity); mDisplayOrientation = CameraUtils.getDisplayOrientation(mDisplayRotation, mCameraId); mCameraDevice.setDisplayOrientation(mDisplayOrientation);
相片方向的设定
由于得到的相片和我们用户使用手机的方向有关,例如用户竖着拍照,那么得到的应该也是竖着的图片,所以我们监听手机方向的变化。如下private MyOrientationEventListener mOrientationListener; @Override public void onCreate(Bundle savedInstanceState) { ... mOrientationListener = new MyOrientationEventListener(this); } @Override public void onPause() { mOrientationListener.disable(); super.onPause(); } @Override public void onResume() { mOrientationListener.enable(); super.onResume(); } private class MyOrientationEventListener extends OrientationEventListener { public MyOrientationEventListener(Context context) { super(context); } @Override public void onOrientationChanged(int orientation) { // We keep the last known orientation. So if the user first orient // the camera then point the camera to floor or sky, we still have // the correct orientation. if (orientation == ORIENTATION_UNKNOWN) return; KSLog2.KSLog().d("onOrientationChanged = " + orientation); } }
通过上面的方法我们就可以监听手机的方向,然后我们通过公式来计算在当前手机的方向下应该设定手机真正的方向(0,90,180,270)这几种方向的一种,如下所示:
// Orientation hysteresis amount used in rounding, in degrees public static final int ORIENTATION_HYSTERESIS = 5; public static int roundOrientation(int orientation, int orientationHistory) { boolean changeOrientation = false; if (orientationHistory == OrientationEventListener.ORIENTATION_UNKNOWN) { changeOrientation = true; } else { int dist = Math.abs(orientation - orientationHistory); dist = Math.min( dist, 360 - dist ); changeOrientation = ( dist >= 45 + ORIENTATION_HYSTERESIS ); } if (changeOrientation) { return ((orientation + 45) / 90 * 90) % 360; } return orientationHistory; }
得到手机真正的方向后,我们就可以计算图片的方向了。如下所以
/** * 获取照片的方向 * @param cameraId 摄像头ID * @param orientation 手机方向 * @return */ public static int getJpegRotation(int cameraId, int orientation) { // See android.hardware.Camera.Parameters.setRotation for // documentation. int rotation = 0; if (orientation != OrientationEventListener.ORIENTATION_UNKNOWN) { Camera.CameraInfo info = CameraHolder.instance().getCameraInfo()[cameraId]; if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) { rotation = (info.orientation - orientation + 360) % 360; } else { // back-facing camera rotation = (info.orientation + orientation) % 360; } } return rotation; }
最后设定图片的方向
// Set rotation and gps data. mJpegRotation = CameraUtils.getJpegRotation(mCameraId, mOrientation); mParameters.setRotation(mJpegRotation); mParameters.set("rotation", mJpegRotation); mCameraDevice.setParameters(mParameters);
预览界面的大小设定
在设定预览界面的时候我们不能任意设定预览界面的大小(会出现异常同时也有可能出现在其他手机不兼容的情况),所以我们应该先查询系统支持的大小,然后通过计算得到最适合的预览界面。如下所示:public static Camera.Size getOptimalPreviewSize(Activity activity, List<Camera.Size> sizes) { if (sizes == null) return null; DeviceInfoUtils.ScreenInfo screenInfo = DeviceInfoUtils.getScreenInfo(activity); //这里得到的是surfaceView的长宽比,你们可以根据自己需要计算自己相机surfaceView的长宽比 final double targetRatio = (screenInfo.width * 1.0f) / (screenInfo.height - activity.getResources().getDimensionPixelOffset(R.dimen.doc_scan_camera_bottom_bar_height)); Camera.Size optimalSize = null; double minRatioDiff = Double.MAX_VALUE; double ratio = 0; for (Camera.Size size : sizes) { if (size.height > size.width) { ratio = ((double) (size.width)) / ((double) size.height); } else { ratio = ((double) (size.height)) / ((double) size.width); } double temp = Math.abs(targetRatio - ratio); if (temp < minRatioDiff && Math.min(size.height, size.width) >= screenInfo.width) { optimalSize = size; minRatioDiff = temp; } } KSLog2.KSLog().d("preview size width = " + optimalSize.width + " height = " + optimalSize.height + " minRatioDiff= " + minRatioDiff); return optimalSize; }
设定预览界面的大小
// Set a preview size that is closest to the viewfinder height and has // the right aspect ratio. List<Camera.Size> sizes = mParameters.getSupportedPreviewSizes(); Camera.Size optimalSize = CameraUtils.getOptimalPreviewSize(mActivity, sizes); Camera.Size original = mParameters.getPreviewSize(); if (!original.equals(optimalSize)) { mParameters.setPreviewSize(optimalSize.width, optimalSize.height); }
总结
在开发相机中需要设定很多参数,其中很多参数都需要查询系统是否支持,然后再去设定系统支持设定中的某一种,例如:图片输出的大小、对焦方式、曝光模式等等,不然容易出现崩溃或者兼容性问题。相关文章推荐
- Android 相机的开发注意事项
- Android开发环境配置注意事项
- Android开发环境配置注意事项
- [Android开发] 注意事项
- Android NDK C++开发注意事项总结
- Android开发 调用照相机实现代码和注意事项
- Cordova/PhoneGap 3.0 Android开发环境注意事项
- Android NDK C++开发注意事项总结
- Android开发 WebView使用注意事项
- 如何提高android程序运行效率,程序员在开发过程中应当注意的一些事项
- android开发的一些注意事项
- Android开发环境配置及注意事项
- Android生存指南:一些开发注意事项
- virtualbox ubuntu虚拟机安装配置android开发环境(eclipse+ndk+sdk)及注意事项
- J2ME转Android游戏开发时注意事项
- Android开发,通迅薄的注意事项
- Android NDK C++开发注意事项总结
- Android生存指南:一些开发注意事项
- 使用Eclipse开发Android源码的一些注意事项
- Android开发中整合测试注意事项