import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;
+import android.graphics.Matrix;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
+import android.media.ExifInterface;
import android.media.ThumbnailUtils;
import android.net.Uri;
import android.os.AsyncTask;
if (bitmap != null) {
thumbnail = ThumbnailUtils.extractThumbnail(bitmap, px, px);
+
+ // Rotate image, obeying exif tag
+ thumbnail = BitmapUtils.rotateImage(thumbnail, mFile.getStoragePath());
// Add thumbnail to cache
addBitmapToCache(imageKey, thumbnail);
mThumbnailsDiskCacheLock.notifyAll(); // Wake any waiting threads
}
}
-
+
}
import com.owncloud.android.ui.dialog.ConfirmationDialogFragment;
import com.owncloud.android.ui.dialog.RemoveFileDialogFragment;
import com.owncloud.android.ui.fragment.FileFragment;
+import com.owncloud.android.utils.BitmapUtils;
import com.owncloud.android.utils.TouchImageViewCustom;
private static final String TAG = PreviewImageFragment.class.getSimpleName();
private boolean mIgnoreFirstSavedState;
+
+ private LoadBitmapTask mLoadBitmapTask = null;
/**
public void onStart() {
super.onStart();
if (getFile() != null) {
- BitmapLoader bl = new BitmapLoader(mImageView, mMessageView, mProgressWheel);
- bl.execute(new String[]{getFile().getStoragePath()});
+ mLoadBitmapTask = new LoadBitmapTask(mImageView, mMessageView, mProgressWheel);
+ mLoadBitmapTask.execute(new String[]{getFile().getStoragePath()});
}
}
+ @Override
+ public void onStop() {
+ super.onStop();
+ if (mLoadBitmapTask != null) {
+ mLoadBitmapTask.cancel(true);
+ mLoadBitmapTask = null;
+ }
+
+ }
+
/**
* {@inheritDoc}
*/
finish();
}
-
- private class BitmapLoader extends AsyncTask<String, Void, Bitmap> {
+
+ private class LoadBitmapTask extends AsyncTask<String, Void, Bitmap> {
/**
* Weak reference to the target {@link ImageView} where the bitmap will be loaded into.
*
* @param imageView Target {@link ImageView} where the bitmap will be loaded into.
*/
- public BitmapLoader(ImageViewCustom imageView, TextView messageView, ProgressBar progressWheel) {
+ public LoadBitmapTask(ImageViewCustom imageView, TextView messageView, ProgressBar progressWheel) {
mImageViewRef = new WeakReference<ImageViewCustom>(imageView);
mMessageViewRef = new WeakReference<TextView>(messageView);
mProgressWheelRef = new WeakReference<ProgressBar>(progressWheel);
String storagePath = params[0];
try {
+ if (isCancelled()) return result;
+
File picture = new File(storagePath);
if (picture != null) {
- //Decode file into a bitmap in real size for being able to make zoom on the image
+ // Decode file into a bitmap in real size for being able to make zoom on
+ // the image
result = BitmapFactory.decodeStream(new FlushedInputStream
(new BufferedInputStream(new FileInputStream(picture))));
}
+ if (isCancelled()) return result;
+
if (result == null) {
mErrorMessageId = R.string.preview_image_error_unknown_format;
Log_OC.e(TAG, "File could not be loaded as a bitmap: " + storagePath);
+ } else {
+ // Rotate image, obeying exif tag.
+ result = BitmapUtils.rotateImage(result, storagePath);
}
} catch (OutOfMemoryError e) {
Log_OC.e(TAG, "Out of memory occured for file " + storagePath, e);
- // If out of memory error when loading image, try to load it scaled
+ if (isCancelled()) return result;
+
+ // If out of memory error when loading or rotating image, try to load it scaled
result = loadScaledImage(storagePath);
if (result == null) {
mErrorMessageId = R.string.preview_image_error_unknown_format;
Log_OC.e(TAG, "File could not be loaded as a bitmap: " + storagePath);
+ } else {
+ // Rotate scaled image, obeying exif tag
+ result = BitmapUtils.rotateImage(result, storagePath);
}
} catch (NoSuchFieldError e) {
mErrorMessageId = R.string.common_error_unknown;
- Log_OC.e(TAG, "Error from access to unexisting field despite protection; file " + storagePath, e);
+ Log_OC.e(TAG, "Error from access to unexisting field despite protection; file "
+ + storagePath, e);
} catch (Throwable t) {
mErrorMessageId = R.string.common_error_unknown;
Log_OC.e(TAG, "Unexpected error loading " + getFile().getStoragePath(), t);
}
+
return result;
}
@Override
+ protected void onCancelled(Bitmap result) {
+ if (result != null) {
+ result.recycle();
+ }
+ }
+
+ @Override
protected void onPostExecute(Bitmap result) {
hideProgressWheel();
if (result != null) {
showErrorMessage();
}
}
-
+
@SuppressLint("InlinedApi")
private void showLoadedImage(Bitmap result) {
if (mImageViewRef != null) {
*/
package com.owncloud.android.utils;
+import com.owncloud.android.lib.common.utils.Log_OC;
+
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
+import android.graphics.Matrix;
import android.graphics.BitmapFactory.Options;
+import android.media.ExifInterface;
/**
* Utility class with methods for decoding Bitmaps.
return inSampleSize;
}
+ /**
+ * Rotate bitmap according to EXIF orientation.
+ * Cf. http://www.daveperrett.com/articles/2012/07/28/exif-orientation-handling-is-a-ghetto/
+ * @param bitmap Bitmap to be rotated
+ * @param storagePath Path to source file of bitmap. Needed for EXIF information.
+ * @return correctly EXIF-rotated bitmap
+ */
+ public static Bitmap rotateImage(Bitmap bitmap, String storagePath){
+ Bitmap resultBitmap = bitmap;
+
+ try
+ {
+ ExifInterface exifInterface = new ExifInterface(storagePath);
+ int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, 1);
+
+ Matrix matrix = new Matrix();
+
+ // 1: nothing to do
+
+ // 2
+ if (orientation == ExifInterface.ORIENTATION_FLIP_HORIZONTAL)
+ {
+ matrix.postScale(-1.0f, 1.0f);
+ }
+ // 3
+ else if (orientation == ExifInterface.ORIENTATION_ROTATE_180)
+ {
+ matrix.postRotate(180);
+ }
+ // 4
+ else if (orientation == ExifInterface.ORIENTATION_FLIP_VERTICAL)
+ {
+ matrix.postScale(1.0f, -1.0f);
+ }
+ // 5
+ else if (orientation == ExifInterface.ORIENTATION_TRANSPOSE)
+ {
+ matrix.postRotate(-90);
+ matrix.postScale(1.0f, -1.0f);
+ }
+ // 6
+ else if (orientation == ExifInterface.ORIENTATION_ROTATE_90)
+ {
+ matrix.postRotate(90);
+ }
+ // 7
+ else if (orientation == ExifInterface.ORIENTATION_TRANSVERSE)
+ {
+ matrix.postRotate(90);
+ matrix.postScale(1.0f, -1.0f);
+ }
+ // 8
+ else if (orientation == ExifInterface.ORIENTATION_ROTATE_270)
+ {
+ matrix.postRotate(270);
+ }
+
+ // Rotate the bitmap
+ resultBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
+ if (resultBitmap != bitmap) {
+ bitmap.recycle();
+ }
+ }
+ catch (Exception exception)
+ {
+ Log_OC.e("BitmapUtil", "Could not rotate the image: " + storagePath);
+ }
+ return resultBitmap;
+ }
+
+
}