Bitmap Not Reading EXIF Data on Decode

為{幸葍}努か 提交于 2021-01-27 07:39:00

问题


My Problem

I have a series of Bitmaps that I would like to load up in the correct orientation.

When I save the image I go in and set the orientation attribute using the 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));

This works fine and if I was to pull this image off of my device it would be in the correct orientation. However, when I then decode my Bitmap later down the line it stays in the camera's default orientation of left-horizontal even if the image was taken in portrait?

My Question

How can I decode the bitmap and take into account its EXIF information?

I don't want to have to rotate the image after I decode it every time as I would have to create another Bitmap and that is memory I don't have.

Thanks in advance.


回答1:


For those that are also stuck on this and have oom issues when manipulating multiple bitmaps here is my solution.

Do not change the exif data like I originally thought in the question - We need this later down the line.

When it comes to decoding the image to view, instead of decoding the full size image just decode the image scaled down to what you need. The following code example contains both the decoding of the bitmap to the device screen size and then it also handles the rotation of the bitmap for you.

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);

}

So the image Bitmap thats returned after calling decodeFileForDisplay(File f); is in the correct orientation and the correct size for you screen saving you tons of memory problems.

I hope it helps someone



来源:https://stackoverflow.com/questions/12950954/bitmap-not-reading-exif-data-on-decode

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!