问题
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