位图解码时无法读取EXIF数据

4

我的问题

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

当我保存图像时,我会使用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信息?
我不想每次解码后都要旋转图像,因为我需要创建另一个位图,这会占用内存。
提前致谢。
1个回答

1

对于那些在处理多个位图时也遇到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);后返回的图像位图将具有正确的方向和适合您屏幕的正确尺寸,从而为您省去大量的内存问题。

我希望这能帮到某些人


没关系,我只是认为提供一个完整的解决方案作为答案会更好。无论如何,感谢您提供的信息,这是一个很好的参考。 - pilcrowpipe
能否在将数据直接旋转到正确的方向时解码位图,而不是创建一个与原始位图完全相同但已旋转的新位图? - android developer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接