android - 位图在解码时不读取 EXIF 数据

标签 android android-camera

我的问题

我有一系列位图,我想以正确的方向加载它们。

当我保存图像时,我进入并使用 ExifInterface

设置方向属性
            ExifInterface exif = new ExifInterface(EXTERNAL_IMAGE_PATH+File.separator+this._currentPhotoName+JPEG_FILE_SUFFIX);
            int rotation = CCDataUtils.exifToDegrees(exif.getAttributeInt(ExifInterface.TAG_ORIENTATION,ExifInterface.ORIENTATION_NORMAL));
            Log.v("PhotoManager", "Rotation:"+rotation);
            if (rotation > 0) {
                exif.setAttribute(ExifInterface.TAG_ORIENTATION,String.valueOf(0));

这很好用,如果我要从我的设备上取下这张图片,它的方向应该是正确的。但是,当我稍后解码我的位图时,即使图像是纵向拍摄的,它仍保持相机的默认左水平方向?

我的问题

如何解码位图并考虑其 EXIF 信息?

我不想每次解码后都必须旋转图像,因为我必须创建另一个位图,而那是我没有的内存。

提前致谢。

最佳答案

对于那些也坚持这一点并且在操作多个位图时遇到 oom 问题的人,这里是我的解决方案。

不要像我最初在问题中想的那样更改 exif 数据 - 我们稍后需要它。

在解码图像以供查看时,不是解码全尺寸图像,而是解码按比例缩小到您需要的图像。下面的代码示例包含将位图解码为设备屏幕尺寸,然后它还为您处理位图的旋转。

public static Bitmap decodeFileForDisplay(File f){

    try {
        //Decode image size
        BitmapFactory.Options o = new BitmapFactory.Options();
        o.inJustDecodeBounds = true;
        BitmapFactory.decodeStream(new FileInputStream(f),null,o);
        DisplayMetrics metrics = MyApplication.getAppContext().getResources().getDisplayMetrics();

        //The new size we want to scale to  
        //final int REQUIRED_SIZE=180;

        int scaleW =  o.outWidth / metrics.widthPixels;
        int scaleH =  o.outHeight / metrics.heightPixels;
        int scale = Math.max(scaleW,scaleH);
        //Log.d("CCBitmapUtils", "Scale Factor:"+scale);
        //Find the correct scale value. It should be the power of 2.

        //Decode with inSampleSize
        BitmapFactory.Options o2 = new BitmapFactory.Options();
        o2.inSampleSize=scale;
        Bitmap scaledPhoto = BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
        try {
            ExifInterface exif = new ExifInterface(f.getAbsolutePath());
            int rotation = CCDataUtils.exifToDegrees(exif.getAttributeInt(ExifInterface.TAG_ORIENTATION,ExifInterface.ORIENTATION_NORMAL));
            if (rotation > 0)
                scaledPhoto = CCBitmapUtils.convertBitmapToCorrectOrientation(scaledPhoto, rotation);

        } catch (IOException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
        return scaledPhoto;

    } catch (FileNotFoundException e) {}
    return null;
    }

public static Bitmap convertBitmapToCorrectOrientation(Bitmap photo,int rotation) {
    int width = photo.getWidth();
    int height = photo.getHeight();


    Matrix matrix = new Matrix();
    matrix.preRotate(rotation);

    return Bitmap.createBitmap(photo, 0, 0, width, height, matrix, false);

}

因此调用 decodeFileForDisplay(File f); 后返回的图像 Bitmap 的方向和大小对于您的屏幕来说都是正确的,从而为您节省了大量的内存问题。

希望对大家有帮助

关于android - 位图在解码时不读取 EXIF 数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12950954/

相关文章:

android - 使用图库图标启动相机 Intent

android - 使用 android.hardware.camera2 设置自定义分辨率和帧率

java - GPS应用距离

android - 无法过渡到 fragment 。期望不同类型的函数

android - 通过迭代失败按多个跨度样式设置文本

android - 在 Debug模式 Android 下连接时找不到 SD 卡

android - IntelliJ Idea 无法识别 ActionBarSherlock 中的兼容性库

android - 摩托罗拉设备上的自定义权限失败

java - 将照片保存到图库时出错 - Android Studio (java)

android - 第二次从相机捕获时无法加载图像