2017-07-01 69 views
1

我已经的Android Camera2 pcitures出现旋转,画廊

但是,当一个应用程序,它拍摄照片,使用Google Camera2 sample,一切正常,我可以把图片,它们将被保存(肖像,风景或自拍)等。我打开手机(三星S7)图库,然后将所有自拍和人像图片旋转90度。风景图片虽然很好。我看过很多关于如何以正确的方向读取图片的帖子,但是如何正确保存它们呢?

我有我自己的画廊在我的应用程序和那里图片加载正确(使用滑翔)没有任何特殊的旋转修复,所以我不知道我做错了什么,最重要的是,我该如何解决这个问题?

+0

将其中一个图像从设备上拉出来,并使用'exiftool'或其他东西进行检查。或者,将一些使用'ExifInterface'的'com.android.support:exifinterface'版本的代码一起扔掉。无论哪种情况,您都在查看是否存在具有期望值的定位EXIF标签。如果存在,那么问题不在于保存图像,而是您正在使用的图库应用程序中的错误。欢迎尝试在保存之前手动旋转图像(并删除方向标记),但可能没有足够的堆空间来执行此操作。 – CommonsWare

+0

如果OTOH,该标签丢失,那么在保存图像的方式上可能存在错误,这需要[mcve]。 – CommonsWare

+0

我在其中一个selfies上运行exiftool,并获得了一个方向标签:“旋转270 CW”。所以我猜画廊有问题吗? – barouf

回答

0

图像查看器应该检查EXIF标签并根据方向标签旋转图像。这允许相机应用程序和类似软件以任何方向保存图像,而不必在保存图像之前旋转图像。

图书馆一样滑翔和毕加索会为你做这个,如果你给他们访问完整的JPEG(例如,fileUricontentUrihttps URL)。这是因为他们可以访问EXIF标记得到的ImageView,因此他们可以告诉ImageView旋转图像。

然而,并非每个人都使用这样的库。 ImageView自己处理诸如Bitmap之类的东西,其中那些EXIF标签在解码过程中已经丢失。

你,作为一个摄像头应用程序的作者,这里有两个主要的选项:

  1. 你可以检查EXIF标签,看到的图像需要旋转,自己旋转它,并保存旋转的图像(删除方向标签,但安排保留其他)。但是,这可能会失败,特别是对于摄像机图像,因为这些图像往往很大。

  2. 你可能耸耸肩,继续前进,因为这不是你的问题。正如你注意到的,其他图库应用程序不会出现问题,因为它们已经过充分测试,并且您尝试的原始图库应用程序没有。

如果使用选项#1,如果您获得OutOfMemoryError,它会变成选项#2。

+0

我想提一提的是,即使使用选项1,看起来这种情况也不同于手机,因为制造商似乎以不同的方式保存图像。我想我会耸耸肩当然。谢谢你的帮助! – barouf

+0

@barouf:“这看起来不同于手机,因为制造商似乎以不同的方式保存图像” - 哦,绝对。从我所看到的,我的猜测是,它与其他任何东西都与相机芯片组相关联。有些会为你旋转图像。其他人只需设置EXIF标签。一些将会是越野车,并且都不会,并且你试图或许使用传感器来确定当时如何保持该装置。 – CommonsWare

+0

与选项1一起使用,您不一定需要检查EXIF。您的应用程序控制捕捉,您可以访问方向传感器,有时这可能会有所帮助。 –

1

您是否在您的静止捕捉请求中使用了JPEG_ORIENTATION控件?如果没有,那可能是问题 - 该控件告诉相机设备如何将最终的JPEG图像旋转为正面朝上。

因此,您需要更新该控件中的值以描述图像传感器当前相对于世界的排列方式。

要做到这一点计算,你需要从加速度计输入(它告诉你哪个方向是向下),然后是一些基本的数学 - 从上面的链接复制此:

private int getJpegOrientation(CameraCharacteristics c, int deviceOrientation) { 
    if (deviceOrientation == android.view.OrientationEventListener.ORIENTATION_UNKNOWN) return 0; 
    int sensorOrientation = c.get(CameraCharacteristics.SENSOR_ORIENTATION); 

    // Round device orientation to a multiple of 90 
    deviceOrientation = (deviceOrientation + 45)/90 * 90; 

    // Reverse device orientation for front-facing cameras 
    boolean facingFront = c.get(CameraCharacteristics.LENS_FACING) == CameraCharacteristics.LENS_FACING_FRONT; 
    if (facingFront) deviceOrientation = -deviceOrientation; 

    // Calculate desired JPEG orientation relative to camera orientation to make 
    // the image upright relative to the device orientation 
    int jpegOrientation = (sensorOrientation + deviceOrientation + 360) % 360; 

    return jpegOrientation; 
} 

其中输入deviceOrientation来自传感器API。