Android图像调整大小和保留EXIF数据(方向,旋转等)

Mik*_*ass 49 android exif image android-camera

如果您的Android应用使用设备的相机拍照,然后调整它的大小(这是很常见的,以减少上传大小),你可能没有意识到,这个调整操作的EXIF元数据.

这可能会导致问题,尤其是当相关设备依赖"方向"标签正确显示图像时.

不同的Android设备以不同的方式处理相机/图像旋转 - 我信赖的'Nexus One似乎总是在捕获后立即旋转图像,因此文件的本机内容在查看时始终是"直立的".然而,其他设备(特别是我测试中的三星手机)不会旋转图像文件的内容 - 而是设置exif'Orientation'标签.无论何时稍后显示图像,相关图像代码都应检测到方向"标签"的存在并适当地旋转图像.但是如果您对图像进行了任何位图处理并将其保存到新文件中,那么所有exif数据都将丢失.

除了Orientation数据之外,您还可能会丢失其他有价值的元数据,例如品牌/型号等.

这使我困惑了几个星期(图像在电话库中显示时显示正常,但随后到达我的服务器时方向错误且没有明显的元数据).我在这里添加这个自我提问来帮助别人.这篇博客文章非常有用:

http://vikaskanani.wordpress.com/2011/07/17/android-re-size-image-without-loosing-exif-information/

Mik*_*ass 44

[自答案]

没有,没有机制可以自动保存元数据,甚至不对任何存在的元素进行快照并批量传输.

相反,您似乎必须使用ExifInterface显式检查特定属性并将它们自己复制到新的映像文件中.

http://developer.android.com/reference/android/media/ExifInterface.html

所以类似于:

ExifInterface oldExif = new ExifInterface(oldImagePath);
String exifOrientation = oldExif.getAttribute(ExifInterface.TAG_ORIENTATION);

if (exifOrientation != null) {
   ExifInterface newExif = new ExifInterface(imagePath);
   newExif.setAttribute(ExifInterface.TAG_ORIENTATION, exifOrientation);
   newExif.saveAttributes();
}
Run Code Online (Sandbox Code Playgroud)


pro*_*m85 32

对于懒惰的,这是一个可重用的功能:

public static void copyExif(String oldPath, String newPath) throws IOException
{
    ExifInterface oldExif = new ExifInterface(oldPath);

    String[] attributes = new String[]
    {
            ExifInterface.TAG_APERTURE,
            ExifInterface.TAG_DATETIME,
            ExifInterface.TAG_DATETIME_DIGITIZED,
            ExifInterface.TAG_EXPOSURE_TIME,
            ExifInterface.TAG_FLASH,
            ExifInterface.TAG_FOCAL_LENGTH,
            ExifInterface.TAG_GPS_ALTITUDE,
            ExifInterface.TAG_GPS_ALTITUDE_REF,
            ExifInterface.TAG_GPS_DATESTAMP,
            ExifInterface.TAG_GPS_LATITUDE,
            ExifInterface.TAG_GPS_LATITUDE_REF,
            ExifInterface.TAG_GPS_LONGITUDE,
            ExifInterface.TAG_GPS_LONGITUDE_REF,
            ExifInterface.TAG_GPS_PROCESSING_METHOD,
            ExifInterface.TAG_GPS_TIMESTAMP,
            ExifInterface.TAG_IMAGE_LENGTH,
            ExifInterface.TAG_IMAGE_WIDTH,
            ExifInterface.TAG_ISO,
            ExifInterface.TAG_MAKE,
            ExifInterface.TAG_MODEL,
            ExifInterface.TAG_ORIENTATION,
            ExifInterface.TAG_SUBSEC_TIME,
            ExifInterface.TAG_SUBSEC_TIME_DIG,
            ExifInterface.TAG_SUBSEC_TIME_ORIG,
            ExifInterface.TAG_WHITE_BALANCE
    };

    ExifInterface newExif = new ExifInterface(newPath);
    for (int i = 0; i < attributes.length; i++)
    {
        String value = oldExif.getAttribute(attributes[i]);
        if (value != null)
            newExif.setAttribute(attributes[i], value);
    }
    newExif.saveAttributes();
}
Run Code Online (Sandbox Code Playgroud)

  • 如果调整大小,请记住更新或不复制TAG_IMAGE_LENGTH和TAG_IMAGE_WIDTH (12认同)

The*_*heo 18

正如其他人指出的那样,您必须将EXIF数据从原始图像复制到最终调整大小的图像.Sanselan Android库通常是最好的.根据Android操作系统版本,ExifInterface有时会破坏EXIF数据.此外,ExifInterface还处理有限数量的Exif标记 - 即只有它"知道"的标记.另一方面,Sanselan将保留所有EXIF标签和标记说明.

这是一篇博客文章,展示如何使用Sanselan复制图像数据:http://bricolsoftconsulting.com/copying-exif-metadata-using-sanselan/

顺便说一下,在Android上我也倾向于旋转图像并删除Orientation EXIF标签.例如,在带有Android 4.03的Nexus S上,相机在EXIF元数据中设置了方向标记,但是webview忽略了该信息并错误地显示了图像.遗憾的是,旋转实际图像数据并删除EXIF方向标记是让每个程序正确显示图像的唯一方法.