没有surfaceView的Android相机图像方向

Posted

技术标签:

【中文标题】没有surfaceView的Android相机图像方向【英文标题】:Android camera image orientation without sufaceView 【发布时间】:2014-05-19 10:21:27 【问题描述】:

我有一项服务,我必须在没有 SurfaceView 的情况下捕获图像,除了结果图像方向,我发现它的角度不正确,一切都运行良好。在 HTC 等小型设备上,我发现它有问题或旋转,因此手动设置旋转以查看它是否正常工作。

if (camInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) 
    parameters.setRotation(270);
  else if (camInfo.facing ==
    Camera.CameraInfo.CAMERA_FACING_BACK) 
    parameters.setRotation(90);
 

但是当检查三星和 HTC 之一(大型设备)时,它会产生角度问题。我发现了一些帖子,我必须在其中放置图像路径,然后尝试设置旋转,但这对我不起作用,即这是因为我在没有 serfaceview 的情况下拍照,然后立即将其发布到服务器。我还尝试了 setCameraOrientation() 的 google 部分代码,但它需要活动视图才能工作,所以我在那里也失败了。

我只需要在发送到服务器之前修复图像的角度,而不需要任何表面视图或活动。

【问题讨论】:

【参考方案1】:

setRotation() 只能选择使用 EXIF 标志。结果是仍然旋转 90° 的图像,但带有描述正确方向的“标志”。并非所有观众都正确考虑了这个标志。具体来说,BitmapFactory 会忽略它。您可以在画布上绘制旋转的位图,或旋转从BitmapFactory.decodeFile() 获取的位图,或在使用 3rd 方库将 JPEG 数据写入 outStream 之前对其进行操作,例如MediaUtil。 android 端口位于GitHub。

【讨论】:

【参考方案2】:

您可以通过 ExifInterface 对象访问图像方向信息。它会给你不同的值,具体取决于手机,如果你在横向或纵向模式下捕获图像。然后你可以根据ExifInterface的信息使用一个矩阵来旋转图片,最后发送到你的服务器上。

知道图像的路径( imagePath ),使用以下代码:

Matrix matrix = new Matrix();   
try            
ExifInterface exif = new ExifInterface(imagePath);
                int orientation = exif.getAttributeInt(
                        ExifInterface.TAG_ORIENTATION,
                        ExifInterface.ORIENTATION_NORMAL);

                switch (orientation) 
                case ExifInterface.ORIENTATION_ROTATE_90:
                    // Change the image orientation
                    matrix.postRotate(90);
                    break;
                case ExifInterface.ORIENTATION_ROTATE_180:
                    // Change the image orientation
                    matrix.postRotate(180);
                    break;
catch (IOException e) 
                e.printStackTrace();
            

然后你使用你的矩阵对象来旋转你的位图:

  rotatedBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(),matrix, true);

在将位图发送到服务器之前,您必须将其保存在某处(外部或内部临时存储)。

希望对你有帮助。

【讨论】:

我不想把它保存在任何地方。我想我以后需要它来清除它,因为正如我所说,它是一个非活动后台运行服务来获取图像所以一种不可见的东西【参考方案3】:

您的旋转设置代码有点过于简单,因此在某些设备上它可能会做错事。不能保证这些是正确的旋转 - 正确答案是设备当前方向的函数,以及设备上传感器的方向。

看看Camera.Parameters.setRotation的示例代码:

public void onOrientationChanged(int orientation) 
  if (orientation == ORIENTATION_UNKNOWN) return;
  android.hardware.Camera.CameraInfo info =
        new android.hardware.Camera.CameraInfo();
  android.hardware.Camera.getCameraInfo(cameraId, info);
  orientation = (orientation + 45) / 90 * 90;
  int rotation = 0;
  if (info.facing == CameraInfo.CAMERA_FACING_FRONT) 
     rotation = (info.orientation - orientation + 360) % 360;
   else   // back-facing camera
     rotation = (info.orientation + orientation) % 360;
  
  mParameters.setRotation(rotation);

如果您没有活动,则必须弄清楚如何以其他方式获取设备的当前方向,但您需要在计算中包含info.orientation

【讨论】:

是的,这就是我没有活动的关键,因为活动的事情我在那里的代码有些成功!

以上是关于没有surfaceView的Android相机图像方向的主要内容,如果未能解决你的问题,请参考以下文章

无法创建支持android 4.0 及更高版本的surfaceview 相机应用。

相机中使用的Android模糊surfaceview

相机的surfaceview在android棒棒糖操作系统中不起作用

Android 自定义相机 - 在矩形内裁剪图像

是否可以裁剪相机预览?

在android中的surfaceview上创建cameraview(掩码)