X-Git-Url: http://git.linex4red.de/pub/Android/ownCloud.git/blobdiff_plain/2e472998c16e504c0c2ceddf7de52a000d7bd7f8..f46dd624f7576faa66d2532b23bdd7221348c87d:/src/com/owncloud/android/ui/preview/PreviewImageFragment.java diff --git a/src/com/owncloud/android/ui/preview/PreviewImageFragment.java b/src/com/owncloud/android/ui/preview/PreviewImageFragment.java index aeca583a..70ab80d9 100644 --- a/src/com/owncloud/android/ui/preview/PreviewImageFragment.java +++ b/src/com/owncloud/android/ui/preview/PreviewImageFragment.java @@ -29,9 +29,14 @@ import android.annotation.SuppressLint; import android.app.Activity; import android.graphics.Bitmap; import android.graphics.BitmapFactory; +import android.graphics.BitmapFactory.Options; +import android.graphics.Matrix; +import android.graphics.Point; +import android.media.ExifInterface; import android.os.AsyncTask; import android.os.Bundle; import android.support.v4.app.FragmentStatePagerAdapter; +import android.view.Display; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; @@ -376,7 +381,6 @@ public class PreviewImageFragment extends FileFragment { String storagePath = params[0]; try { - File picture = new File(storagePath); if (picture != null) { @@ -391,8 +395,15 @@ public class PreviewImageFragment extends FileFragment { } } catch (OutOfMemoryError e) { - mErrorMessageId = R.string.preview_image_error_unknown_format; 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 + 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); + } } catch (NoSuchFieldError e) { mErrorMessageId = R.string.common_error_unknown; @@ -403,9 +414,80 @@ public class PreviewImageFragment extends FileFragment { Log_OC.e(TAG, "Unexpected error loading " + getFile().getStoragePath(), t); } + + result = rotateImage(result, storagePath); + + return result; } + /** + * 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 + */ + private 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); + } + catch (Exception exception) + { + Log_OC.e(TAG, "Could not rotate the image: " + storagePath); + } + return resultBitmap; + } + @Override protected void onPostExecute(Bitmap result) { hideProgressWheel(); @@ -509,4 +591,60 @@ public class PreviewImageFragment extends FileFragment { return totalBytesSkipped; } } + + /** + * Load image scaled + * @param storagePath: path of the image + * @return Bitmap + */ + @SuppressWarnings("deprecation") + private Bitmap loadScaledImage(String storagePath) { + + Log_OC.d(TAG, "Loading image scaled"); + + // set desired options that will affect the size of the bitmap + BitmapFactory.Options options = new Options(); + options.inScaled = true; + options.inPurgeable = true; + if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.GINGERBREAD_MR1) { + options.inPreferQualityOverSpeed = false; + } + if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB) { + options.inMutable = false; + } + // make a false load of the bitmap - just to be able to read outWidth, outHeight and outMimeType + options.inJustDecodeBounds = true; + BitmapFactory.decodeFile(storagePath, options); + + int width = options.outWidth; + int height = options.outHeight; + int scale = 1; + + Display display = getActivity().getWindowManager().getDefaultDisplay(); + Point size = new Point(); + int screenWidth; + int screenHeight; + if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB_MR2) { + display.getSize(size); + screenWidth = size.x; + screenHeight = size.y; + } else { + screenWidth = display.getWidth(); + screenHeight = display.getHeight(); + } + + if (width > screenWidth) { + // second try to scale down the image , this time depending upon the screen size + scale = (int) Math.floor((float)width / screenWidth); + } + if (height > screenHeight) { + scale = Math.max(scale, (int) Math.floor((float)height / screenHeight)); + } + options.inSampleSize = scale; + + // really load the bitmap + options.inJustDecodeBounds = false; // the next decodeFile call will be real + return BitmapFactory.decodeFile(storagePath, options); + + } }