[Android] AudioUtil: use a memory efficient way to read and scale down covers

Ludovic Fauvet git at videolan.org
Thu Oct 18 12:57:24 CEST 2012


vlc-ports/android | branch: master | Ludovic Fauvet <etix at videolan.org> | Thu Oct 18 12:33:09 2012 +0200| [62776310c1cb6bd3e4902088032987590724f184] | committer: Ludovic Fauvet

AudioUtil: use a memory efficient way to read and scale down covers

It should reduce significantly the number of OutOfMemoryError.

> http://git.videolan.org/gitweb.cgi/vlc-ports/android.git/?a=commit;h=62776310c1cb6bd3e4902088032987590724f184
---

 vlc-android/src/org/videolan/vlc/Util.java         |    5 ++++
 .../src/org/videolan/vlc/gui/audio/AudioUtil.java  |   30 ++++++++++++++++----
 2 files changed, 30 insertions(+), 5 deletions(-)

diff --git a/vlc-android/src/org/videolan/vlc/Util.java b/vlc-android/src/org/videolan/vlc/Util.java
index 8a11d01..55c9889 100644
--- a/vlc-android/src/org/videolan/vlc/Util.java
+++ b/vlc-android/src/org/videolan/vlc/Util.java
@@ -142,6 +142,11 @@ public class Util {
     }
 
     public static Bitmap scaleDownBitmap(Context context, Bitmap bitmap, int width) {
+        /*
+         * This method can lead to OutOfMemoryError!
+         * If the source size is more than twice the target size use
+         * the optimized version available in AudioUtil::readCoverBitmap
+         */
         if (bitmap != null) {
             final float densityMultiplier = context.getResources().getDisplayMetrics().density;
             int w = (int) (width * densityMultiplier);
diff --git a/vlc-android/src/org/videolan/vlc/gui/audio/AudioUtil.java b/vlc-android/src/org/videolan/vlc/gui/audio/AudioUtil.java
index abd1592..a3e65c0 100644
--- a/vlc-android/src/org/videolan/vlc/gui/audio/AudioUtil.java
+++ b/vlc-android/src/org/videolan/vlc/gui/audio/AudioUtil.java
@@ -229,12 +229,32 @@ public class AudioUtil {
         }
     }
 
-    private static Bitmap readCoverBitmap(Context context, String path, int width) {
-        Bitmap cover = BitmapFactory.decodeFile(path);
+    private static Bitmap readCoverBitmap(Context context, String path, int dipWidth) {
+        Bitmap cover = null;
+        BitmapFactory.Options options = new BitmapFactory.Options();
+        int width = Util.convertDpToPx(dipWidth);
+
+        /* Get the resolution of the bitmap without allocating the memory */
+        options.inJustDecodeBounds = true;
+        BitmapFactory.decodeFile(path, options);
+
+        if (options.outWidth > 0 && options.outHeight > 0) {
+            options.inJustDecodeBounds = false;
+            options.inSampleSize = 2;
+
+            // Find the best decoding scale for the bitmap
+            while( options.outWidth / options.inSampleSize > width)
+                options.inSampleSize++;
+            options.inSampleSize--;
 
-        // scale down if requested
-        if (cover != null && width > 0)
-            cover = Util.scaleDownBitmap(context, cover, width);
+            // Decode the file (with memory allocation this time)
+            cover = BitmapFactory.decodeFile(path, options);
+
+            if (cover != null && options.outWidth > width) {
+                int height = (int) (width * options.outHeight / ((double) options.outWidth));
+                cover = Bitmap.createScaledBitmap(cover, width, height, false);
+            }
+        }
 
         return cover;
     }



More information about the Android mailing list