1. Why do you want to load the thumbnail image?
Sometimes you don't need to show the original, just show the thumbnail of the picture and save the memory. For example: NetEase news in the picture browsing, the left to show the Little lion Picture is a thumbnail, click on this image, will show the original.
2. How, what do you do?
Http://developer.android.com/training/displaying-bitmaps/load-bitmap.html gives a way to load a thumbnail image of a picture.
Bitmapfactory#decodefile (String pathName, Bitmapfactory.options opts), opts can specify two parameters for Injustdecodebounds and insamplesize. When Injustdecodebounds is specified, only the length and width of the image are resolved, not the picture is loaded. When Insamplesize is specified, a thumbnail is loaded according to Insamplesize. For example insamplesize=4, the loaded thumbnail is 1/4 of the size of the original image.
How much do you want to set insamplesize? Assuming the original image is 1500x700, the space we set aside for the thumbnail is 100x100. So Insamplesize=min (1500/100, 700/100) = 7. The thumbnail we can get is 1/7 of the original image. Here if you want to ask 15:7 of the pictures how to show in the area of 1:1, please go to see the ScaleType property of ImageView.
But the fact is not so perfect, although set insamplesize=7, but the resulting thumbnail is 1/4 of the original, because Insamplesize can only be 2 of the whole number of power, if not, down to achieve the maximum of 2 of the whole number of power, 7 down looking for 2 of the whole power, is 4.
How can we not waste memory? Big Bear classmate found a method: Bitmap#createscaledbitmap (Bitmap src, int dstwidth, int dstheight, Boolean filter), This method can generate a bitmap of a specified size bitmap, which can enlarge the image or reduce the image.
Final thumbnail loading process:
1. Use Injustdecodebounds to read the length and width of the bitmap.
2. Calculate the size of the insamplesize according to the length and width of the bitmap and the target thumbnail.
3. Using Insamplesize, load a larger thumbnail a
4. Using Createscasebitmap, use thumbnail A to generate the thumbnail b we need.
5. Shrink-back sketch A.
3. Notice, things to be aware of
Createscasebitmap if the original and target thumbnail size is the same, then a new bitmap will not be generated to directly return bitmap, so when recycling, to determine whether thumbnail A is thumbnail b, if so, do not recycle.
4. Code
?
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455 |
/**
* http://developer.android.com/training/displaying-bitmaps/load-bitmap.html
*/
public class BitmapUtils {
private static int calculateInSampleSize(BitmapFactory.Options options,
int reqWidth,
int reqHeight) {
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize =
1
;
if (height > reqHeight || width > reqWidth) {
final int halfHeight = height /
2
;
final int halfWidth = width /
2
;
while ((halfHeight / inSampleSize) > reqHeight
&& (halfWidth / inSampleSize) > reqWidth) {
inSampleSize *=
2
;
}
}
return inSampleSize;
}
// 如果是放大图片,filter决定是否平滑,如果是缩小图片,filter无影响
private static Bitmap createScaleBitmap(Bitmap src,
int dstWidth,
int dstHeight) {
Bitmap dst = Bitmap.createScaledBitmap(src, dstWidth, dstHeight,
false
);
if (src != dst) {
// 如果没有缩放,那么不回收
src.recycle();
// 释放Bitmap的native像素数组
}
return dst;
}
// 从Resources中加载图片
public static Bitmap decodeSampledBitmapFromResource(Resources res,
int resId,
int reqWidth,
int reqHeight) {
final BitmapFactory.Options options =
new BitmapFactory.Options();
options.inJustDecodeBounds =
true
;
BitmapFactory.decodeResource(res, resId, options);
// 读取图片长款
options.inSampleSize = calculateInSampleSize(options, reqWidth,
reqHeight);
// 计算inSampleSize
options.inJustDecodeBounds =
false
;
Bitmap src = BitmapFactory.decodeResource(res, resId, options);
// 载入一个稍大的缩略图
return createScaleBitmap(src, reqWidth, reqHeight);
// 进一步得到目标大小的缩略图
}
// 从sd卡上加载图片
public static Bitmap decodeSampledBitmapFromFd(String pathName,
int reqWidth,
int reqHeight) {
final BitmapFactory.Options options =
new BitmapFactory.Options();
options.inJustDecodeBounds =
true
;
BitmapFactory.decodeFile(pathName, options);
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
options.inJustDecodeBounds =
false
;
Bitmap src = BitmapFactory.decodeFile(pathName, options);
return createScaleBitmap(src, reqWidth, reqHeight);
}
}
|
5. Test code
Code Download LINK http://download.csdn.net/detail/u011267546/7485045
In the drawable-xxhdpi directory, a total of four large figures, each average 5-6mb, altogether 22.9MB. If the original loading is easy, it crashes. If loaded using the method above, only 234KB is loaded. Here's how 234KB came, 4 ImageView, target size is 75dip*50dip, on my phone galaxynexus above, converted to PX is 150px*100px=15000 pixels, each pixel using argb_ 8888-way Storage, 4 bytes required. A picture needs 15000*4=60000 bytes, a total of 4 bitmap, then is 60000*4=240000 byte =234.375 KB.
How much memory is needed if it is covered with a screen? My phone is 768*1280 pixels, argb_8888 way storage, 4 bytes per pixel, then is 768*1280*4=3840KB=3.75MB. So, to cache 3 screen images, it's about 11MB. When doing the internal cache, it is necessary to consider this problem.