diff options
author | George Mount <mount@google.com> | 2013-06-18 17:52:35 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2013-06-18 17:52:36 +0000 |
commit | 784000450a39f4b07817c5cefe0c407b6a5f86da (patch) | |
tree | cd4871a2c3d45e3baa8a74f1aa8f8fc5629db58c /src | |
parent | 608e27fb708aa24afe5790b0f0825c977a7df784 (diff) | |
parent | d90e44e196d4c4e3e4c6f21cec3c8ad8c4d16e9a (diff) | |
download | android_packages_apps_Snap-784000450a39f4b07817c5cefe0c407b6a5f86da.tar.gz android_packages_apps_Snap-784000450a39f4b07817c5cefe0c407b6a5f86da.tar.bz2 android_packages_apps_Snap-784000450a39f4b07817c5cefe0c407b6a5f86da.zip |
Merge "Add decoding to a smaller image by sampling and scaling." into gb-ub-photos-carlsbad
Diffstat (limited to 'src')
-rw-r--r-- | src/com/android/photos/data/BitmapDecoder.java | 69 |
1 files changed, 63 insertions, 6 deletions
diff --git a/src/com/android/photos/data/BitmapDecoder.java b/src/com/android/photos/data/BitmapDecoder.java index c5101cdfb..0671e73ca 100644 --- a/src/com/android/photos/data/BitmapDecoder.java +++ b/src/com/android/photos/data/BitmapDecoder.java @@ -23,6 +23,7 @@ import android.util.Log; import android.util.Pools.Pool; import android.util.Pools.SynchronizedPool; +import com.android.gallery3d.common.BitmapUtils; import com.android.gallery3d.common.Utils; import java.io.BufferedInputStream; @@ -43,6 +44,7 @@ public class BitmapDecoder { private static final int POOL_SIZE = 4; private static final int TEMP_STORAGE_SIZE_BYTES = 16 * 1024; private static final int HEADER_MAX_SIZE = 128 * 1024; + private static final int NO_SCALING = -1; private static final Pool<BitmapFactory.Options> sOptions = new SynchronizedPool<BitmapFactory.Options>(POOL_SIZE); @@ -95,7 +97,7 @@ public class BitmapDecoder { } }; - private static <T> Bitmap delegateDecode(Decoder<T> decoder, T input) { + private static <T> Bitmap delegateDecode(Decoder<T> decoder, T input, int width, int height) { BitmapFactory.Options options = getOptions(); GalleryBitmapPool pool = GalleryBitmapPool.getInstance(); try { @@ -104,7 +106,12 @@ public class BitmapDecoder { return null; } options.inJustDecodeBounds = false; - Bitmap reuseBitmap = pool.get(options.outWidth, options.outHeight); + Bitmap reuseBitmap = null; + if (width != NO_SCALING && options.outWidth >= width && options.outHeight >= height) { + setScaling(options, width, height); + } else { + reuseBitmap = pool.get(options.outWidth, options.outHeight); + } options.inBitmap = reuseBitmap; Bitmap decodedBitmap = decoder.decode(input, options); if (reuseBitmap != null && decodedBitmap != reuseBitmap) { @@ -130,7 +137,7 @@ public class BitmapDecoder { if (!in.markSupported()) { in = new BufferedInputStream(in); } - return delegateDecode(sStreamDecoder, in); + return delegateDecode(sStreamDecoder, in, NO_SCALING, NO_SCALING); } finally { Utils.closeSilently(in); } @@ -141,27 +148,77 @@ public class BitmapDecoder { } public static Bitmap decodeFile(String path) { - return delegateDecode(sFileDecoder, path); + return delegateDecode(sFileDecoder, path, NO_SCALING, NO_SCALING); } public static Bitmap decodeByteArray(byte[] data) { - return delegateDecode(sByteArrayDecoder, data); + return delegateDecode(sByteArrayDecoder, data, NO_SCALING, NO_SCALING); } public static void put(Bitmap bitmap) { GalleryBitmapPool.getInstance().put(bitmap); } + /** + * Decodes to a specific size. If the dimensions of the image don't match + * width x height, the resulting image will be in the proportions of the + * decoded image, but will be scaled to fill the dimensions. For example, if + * width and height are 10x10 and the image is 200x100, the resulting image + * will be scaled/sampled to 20x10. + */ + public static Bitmap decodeFile(String path, int width, int height) { + return delegateDecode(sFileDecoder, path, width, height); + } + + /** @see #decodeFile(String, int, int) */ + public static Bitmap decodeByteArray(byte[] data, int width, int height) { + return delegateDecode(sByteArrayDecoder, data, width, height); + } + + /** @see #decodeFile(String, int, int) */ + public static Bitmap decode(InputStream in, int width, int height) { + try { + if (!in.markSupported()) { + in = new BufferedInputStream(in); + } + return delegateDecode(sStreamDecoder, in, width, height); + } finally { + Utils.closeSilently(in); + } + } + private static BitmapFactory.Options getOptions() { BitmapFactory.Options opts = sOptions.acquire(); if (opts == null) { opts = new BitmapFactory.Options(); opts.inMutable = true; opts.inPreferredConfig = Config.ARGB_8888; - opts.inSampleSize = 1; opts.inTempStorage = new byte[TEMP_STORAGE_SIZE_BYTES]; } + opts.inSampleSize = 1; + opts.inDensity = 1; + opts.inTargetDensity = 1; return opts; } + + // Sets the options to sample then scale the image so that the image's + // minimum dimension will match side. + private static void setScaling(BitmapFactory.Options options, int width, int height) { + float widthScale = ((float)options.outWidth)/ width; + float heightScale = ((float) options.outHeight)/height; + int side = (widthScale < heightScale) ? width : height; + options.inSampleSize = BitmapUtils.computeSampleSize(options.outWidth, options.outHeight, + side, BitmapUtils.UNCONSTRAINED); + int constraint; + if (options.outWidth < options.outHeight) { + // Width is the constraint. Scale so that width = side. + constraint = options.outWidth; + } else { + // Height is the constraint. Scale so that height = side. + constraint = options.outHeight; + } + options.inDensity = constraint / options.inSampleSize; + options.inTargetDensity = side; + } } |