ss1271's Site

风餐露宿,不可一日无码.

如何解决Android相机Preview Overlay和取景框方向问题

| Comments

上个月因工作需要手动设定Preview(取景框)上的图像和图像大小等等,所以直接Intent调用系统相机这个最简便易行简单粗暴的方法就不可取了。实现一个相机类其实没有听上去那么复杂,Android的开发文档里面提供了非常详尽的步骤,戳链接。 本文要说的是两个问题,第一个是取景框Overlay。 有些时候自定义相机类需要提供一些可以在取景时覆盖到取景框上面的东西(比如相框什么的),这个做起来很简单,直接在相机画面的XML Layout里面给定一个背景透明的图片即可。 第二个是相机方向问题。我需要固定让相机以Portrait方式,也就是竖屏方式拍照。 此问题比较麻烦,而且Android文档上也好,StackOverflow也好都有五花八门的解决方案。可是如果你试过文档上面的例子你会发现:例子代码跑在某些设备上(比如我的Galaxy Nexus, JellyBean 4.1系统)是没有任何问题的,意思是你取景的方向和预览方向一致。而在另一些设备上,会出现取景90度旋转(恕我记不清楚是逆时针还是顺时针方向了)的问题,并且如果你做了进一步研究,依照网上代码修改一下的话,还有可能会出现刚刚没有方向问题的设备出现90度旋转。总之此问题很麻烦也很恼人,所以希望本文可以帮到读者。 这个我最后还是搞出一个通吃的解决方案,所以应该是不论你放到什么设备上,相机照完之后给的预览图总能是(Portrait)方向的。 首先Set一下Orientation,方法的来源依然是Android开发文档: 注意这里给前摄像头做了镜像翻转。 [java] 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; // do mirror flip } else { // back-facing result = (info.orientation - degrees + 360) % 360; } camera.setDisplayOrientation(result); } [/java] 然后运行一下看看,是不是还是逆时针90度哇?嗯,因为此时相机info返回的90,而你的屏幕(也就是degree值)是0(portrait),这样最后result值算出来还是90度,所以也难怪依旧逆时针90度。为了抵消屏幕的角度,你需要在相机preview layout里面把orientation改成landscape。这样一来屏幕的degree就是90,result算出来就是0。
public final void setDisplayOrientation (int degrees) Since: API Level 8 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.
值得一提的是,根据文档,setDisplayOrientation 这个方法貌似也会改变相机图片的方向,这样就正合我意图,因为我需要set相机为portrait方向并且生成方向一致的图像。

Comments