android - 设置 Android 照片 EXIF 方向

标签 android camera android-camera exif android-orientation

我编写了一个以编程方式拍摄照片的 Android Activity 。我想将图像保存为具有正确 EXIF 方向数据的 JPEG(就像 native Android 相机应用程序自动执行的那样)。

这是实际拍照的方法(我删除了 try/catch block ):

private void takePhoto() {

    camera = Camera.open();
    SurfaceTexture dummySurfaceTexture = new SurfaceTexture(0);
    camera.setPreviewTexture(dummySurfaceTexture);
    camera.startPreview();
    camera.takePicture(null, null, jpgCallback);
}

...和回调:

private Camera.PictureCallback jpgCallback = new Camera.PictureCallback() {
    public void onPictureTaken(byte[] data, Camera camera) {

        releaseCamera();
        savePhoto(data);
};

照片拍摄正确,但我的问题是 EXIF 数据显示方向设置为“图像方向:顶部,左手”,无论设备的方向如何,因此当我上传照片时出现颠倒或旋转。

我真的需要手动捕捉设备方向(滚动、俯仰、方位角)并自己编写 EXIF 方向吗?相机应用程序如何自动正确写入这些数据?有谁知道正确设置此属性的方法吗?

编辑:我无法使用屏幕方向,因为 Activity 已锁定为纵向模式。

最佳答案

您不必自己编写 EXIF 方向,但您需要在拍照前告知相机子系统您设备的方向。它自己无法访问该信息。设置后,相机子系统将设置 EXIF 字段或旋转图像数据以正确定位图像(这取决于您的特定设备)。

要告诉相机您想要的静态图片方向,请使用 Camera.Parameters.setRotation() :

开发者文档中有关于如何正确使用它的引用代码,这有点棘手,因为您设置的值取决于 1) 相机传感器的方向和 2) UI 的方向,相对于设备的正常方向。我在这里复制了示例代码,它使用了 OrientationEventListener并假设您有一个名为 mParameters 的 Camera.Parameters 对象:

 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);
}

然后在调用 takePicture 之前,您需要调用 Camera.setParameters(mParameters)。

在您的特定情况下,您可能想在拍照前查询方向,并使用示例代码中的逻辑来计算旋转。然后通过Camera.getParameters()获取相机参数,调用setRotation,再调用Camera.setParameters()。

关于android - 设置 Android 照片 EXIF 方向,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23205759/

相关文章:

android - 如果设备已经在 Geofence android 中,则停止初始触发

c# - FindViewById() 如何工作?

c# - 使相机 LookDirection 看前面

android - html 输入捕获 ="camera"不起作用,它会在 phonegap 应用程序 (android) 上打开一个画廊

android - 访问 Android 相机框架而不进行预览

android - 获取 id 可绘制资源数组

android: OnEditorActionListener 停止应用程序

android - 在 OpenCL 内核中读取 GL_UNSIGNED_BYTE OpenGL texture2D (android)

Swift:同时进行自动对焦/曝光和连续自动对焦/曝光?

android - 在 android 的下一个 Activity 的 videoView 中传输录制的摄像机视频(使用 Media Recorder)