• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2012 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.contacts.common.util;
18 
19 import android.graphics.Bitmap;
20 import android.graphics.BitmapFactory;
21 
22 /**
23  * Provides static functions to decode bitmaps at the optimal size
24  */
25 public class BitmapUtil {
BitmapUtil()26     private BitmapUtil() {}
27 
28     /**
29      * Returns Width or Height of the picture, depending on which size is smaller. Doesn't actually
30      * decode the picture, so it is pretty efficient to run.
31      */
getSmallerExtentFromBytes(byte[] bytes)32     public static int getSmallerExtentFromBytes(byte[] bytes) {
33         final BitmapFactory.Options options = new BitmapFactory.Options();
34 
35         // don't actually decode the picture, just return its bounds
36         options.inJustDecodeBounds = true;
37         BitmapFactory.decodeByteArray(bytes, 0, bytes.length, options);
38 
39         // test what the best sample size is
40         return Math.min(options.outWidth, options.outHeight);
41     }
42 
43     /**
44      * Finds the optimal sampleSize for loading the picture
45      * @param originalSmallerExtent Width or height of the picture, whichever is smaller
46      * @param targetExtent Width or height of the target view, whichever is bigger.
47      *
48      * If either one of the parameters is 0 or smaller, no sampling is applied
49      */
findOptimalSampleSize(int originalSmallerExtent, int targetExtent)50     public static int findOptimalSampleSize(int originalSmallerExtent, int targetExtent) {
51         // If we don't know sizes, we can't do sampling.
52         if (targetExtent < 1) return 1;
53         if (originalSmallerExtent < 1) return 1;
54 
55         // Test what the best sample size is. To do that, we find the sample size that gives us
56         // the best trade-off between resulting image size and memory requirement. We allow
57         // the down-sampled image to be 20% smaller than the target size. That way we can get around
58         // unfortunate cases where e.g. a 720 picture is requested for 362 and not down-sampled at
59         // all. Why 20%? Why not. Prove me wrong.
60         int extent = originalSmallerExtent;
61         int sampleSize = 1;
62         while ((extent >> 1) >= targetExtent * 0.8f) {
63             sampleSize <<= 1;
64             extent >>= 1;
65         }
66 
67         return sampleSize;
68     }
69 
70     /**
71      * Decodes the bitmap with the given sample size
72      */
decodeBitmapFromBytes(byte[] bytes, int sampleSize)73     public static Bitmap decodeBitmapFromBytes(byte[] bytes, int sampleSize) {
74         final BitmapFactory.Options options;
75         if (sampleSize <= 1) {
76             options = null;
77         } else {
78             options = new BitmapFactory.Options();
79             options.inSampleSize = sampleSize;
80         }
81         return BitmapFactory.decodeByteArray(bytes, 0, bytes.length, options);
82     }
83 }
84