فهرست منبع

Fixed bug. When previewing a big image, sometimes it is not possible load it because there is an out of memory error

jabarros 10 سال پیش
والد
کامیت
3b79715686
1فایلهای تغییر یافته به همراه67 افزوده شده و 2 حذف شده
  1. 67 2
      src/com/owncloud/android/ui/preview/PreviewImageFragment.java

+ 67 - 2
src/com/owncloud/android/ui/preview/PreviewImageFragment.java

@@ -29,9 +29,12 @@ import android.annotation.SuppressLint;
 import android.app.Activity;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
+import android.graphics.BitmapFactory.Options;
+import android.graphics.Point;
 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 +379,6 @@ public class PreviewImageFragment extends FileFragment {
             String storagePath = params[0];
             try {
 
-
                 File picture = new File(storagePath);
 
                 if (picture != null) {
@@ -391,8 +393,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;
@@ -509,4 +518,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);
+
+    }
 }