如何从 Android 相机图像中去除 EXIF 数据

Posted

技术标签:

【中文标题】如何从 Android 相机图像中去除 EXIF 数据【英文标题】:How to strip EXIF data from Android Camera image 【发布时间】:2014-12-15 03:51:33 【问题描述】:

我需要在我的应用中将照片从相机上传到服务器。它适用于大多数设备。但是一些设备导致图像旋转 90',这不是我想要的行为。经过研究,我知道这是由于附有图像的 EXIF 数据。为了从图像位图中去除 EXIF 数据,我尝试了各种方法,例如调整图像大小等,但没有一个对我有用。请任何人提出执行此任务的方法。

【问题讨论】:

根据您的要求,您是否能够从图像中去除 EXIF 数据?此处给出的解决方案会旋转图像。 【参考方案1】:

试试这个,

public static Bitmap getImage(Context context, Uri uri)
            throws FileNotFoundException, IOException 

        InputStream input = context.getContentResolver().openInputStream(uri);

        BitmapFactory.Options onlyBoundsOptions = new BitmapFactory.Options();
        onlyBoundsOptions.inJustDecodeBounds = true;
        onlyBoundsOptions.inDither = true;// optional
        onlyBoundsOptions.inPreferredConfig = Bitmap.Config.ARGB_8888;// optional
        BitmapFactory.decodeStream(input, null, onlyBoundsOptions);
        input.close();

        if ((onlyBoundsOptions.outWidth == -1)
                || (onlyBoundsOptions.outHeight == -1))
            return null;

        BitmapFactory.Options bitmapOptions = new BitmapFactory.Options();
        bitmapOptions.inJustDecodeBounds = false;
        bitmapOptions.inDither = true;
        bitmapOptions.inPreferredConfig = Bitmap.Config.ARGB_8888;// optional
        input = context.getContentResolver().openInputStream(uri);
        Bitmap bitmap = BitmapFactory.decodeStream(input, null, bitmapOptions);
        input.close();

        ExifInterface ei = new ExifInterface(uri.getPath());
        int orientation = ei.getAttributeInt(ExifInterface.TAG_ORIENTATION,
                ExifInterface.ORIENTATION_NORMAL);

        switch (orientation) 
        case ExifInterface.ORIENTATION_ROTATE_90:
            bitmap = rotateImage(bitmap, 90);
            break;
        case ExifInterface.ORIENTATION_ROTATE_180:
            bitmap = rotateImage(bitmap, 180);
            break;
        

        return bitmap;
    

这里的uri是从相机拍摄的图像的uri。

理解exif orientation:转到http://www.impulseadventure.com/photo/exif-orientation.html

【讨论】:

位图从何而来? 但是你的代码是做什么的?总是轮换?请澄清。 它实际上是在执行两个任务:Ist 是从 uri 到 input.close() 获取位图,然后从图像中获取方向标签,如果它被相机旋转,那么它将旋转。 但最初的请求不是轮换。 是的,仅当它不是每次都被相机有意旋转时(由于方向变化或相机的硬件,如 Galaxy s3 参见***.com/q/11023696/2274724),才旋转位图。【参考方案2】:

这里我们使用 ExifInterface 对象来读取 JPEG 文件中的标签并获取图像的方向属性,例如

// Variable to store the corrected bitmap.
Bitmap correctedBitMap = null;

ExifInterface exifInterface = new ExifInterface(<PATH OF YOUR PHOTO>);
int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);

现在整数变量 orientation 包含有关图像旋转多少的信息,然后根据 ExifInterface 常量值检查这些信息并分别进行更改。

switch(orientation) 
    case ExifInterface.ORIENTATION_ROTATE_90:
        correctedBitMap = rotateImage(<YOUR BITMAP OBJECT>, 90);
        break;

    case ExifInterface.ORIENTATION_ROTATE_180:
        correctedBitMap = rotateImage(<YOUR BITMAP OBJECT>, 180);
        break;

rotateImage 方法的代码如下:

private Bitmap rotateImage(Bitmap source, float angle) 

    Bitmap bitmap = null;
    Matrix matrix = new Matrix();
    matrix.postRotate(angle);
    try 
        bitmap = Bitmap.createBitmap(source, 0, 0, source.getWidth(), source.getHeight(),
            matrix, true);
     catch (OutOfMemoryError e) 
        e.printStackTrace();
    
    return bitmap;

【讨论】:

感谢您的努力。实际上我已经在请求URI 加载位图。问题是因为应用程序中相机拍摄的照片是临时存储的。所以当我再次请求URI 时,它会导致崩溃。还有什么建议吗?有没有办法在Bitmap 对象上执行此功能? 为此你可以看看我的这个答案***.com/a/26463347/2330675。在这里检查最后一段代码。

以上是关于如何从 Android 相机图像中去除 EXIF 数据的主要内容,如果未能解决你的问题,请参考以下文章

将带有 exif 的图像转换为 NSData 类型

从安卓相机中提取EXIF数据

如何在Android中将exif数据写入图像?

设置 Android 照片 EXIF 方向

从图库中选择的 Android 图像方向始终为 0:Exif TAG

android中三星设备上的相机捕捉方向