Bitmap优化
Bitmap解码
Bitmap解码
-常见的jpg(有损压缩),png(无损压缩),webp(结合两者优点,android4.2之后支持)使图像的存储格式。
-Android中要显示图片必须先经过解码(decode)读取图像的数据到内存中。
-BitmapFactory提供了常用的一些decode方法。
-图片真正占用的内存大小要看decode之后的数据大小。 Bitmap解码耗时,最好放置异步线程
Bitmap复用
Bitmap复用工具--第三方库glide
//指向一个已经创建的对象mCurrentBitmap,解码新的bitmap就会复用其内存
mBitmapOptions.inBitmap=mCurrentBitmap;
mCurrentBitmap=BitmapFactory.decodeFile(filename,mBitmapOptions);
Bitmap缩放
- 按比例缩放
//缩放到指定的大小
//从一个inBmap获取指定大小的Bitmap
createScaledBitmap(inBmp,64,128);
//缩放到原图的1/4
mBitmapOptions.inSampleSize=4;
mCurrentBitmap=BitmapFactory.decodeFile(fileName,mBitmapOptions);
//缩放为(int)dstWidth/srcWidth
mBitmapOptions.inScaled=true;
mBitmapOptions.inDensity=srcWidth;
mBitmapOptions.inTargetDensity=dstWidth;
mCurrentBitmap=BitmapFactory.decodeResources(getResources(),mImageId,mBitmapOptions);
//先缩放为1/4,再缩放(int)dstWidth*4/srcWidth
//这种缩放效率会很快
mBitmapOptions.inScaled=true;
mBitmapOptions.inSampleSize=4;
mBitmapOptions.inDensity=srcWidth;
mBitmapOptions.inTargetDensity=dstWidth*mBitmapOptions.inSampleSize;
mCurrentBitmap=BitmapFactory.decodeFile(fileName,mBitmapOptions);
- 不加载图片至内存就获取原图的宽和高
mBitmapOptions.inJustDecodeBounds=true;
BitmapFactory.decodeFile(fileName,mBitmapOptions);
srcWidth = mBitmapOptions.outWidth;
srcHeight= mBitmapOptions.outHeight;
- 代码演示源代码
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);
options.inJustDecodeBounds = false;
return BitmapFactory.decodeResource(res, resId, options);
}
```
```
//计算inSampleSize
public 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) {
if (width > height) {
inSampleSize = Math.round((float) height / (float) reqHeight);
} else {
inSampleSize = Math.round((float) width / (float) reqWidth);
}
final float totalPixels = width * height;
final float totalReqPixelsCap = reqWidth * reqHeight * 2;
while (totalPixels / (inSampleSize * inSampleSize) > totalReqPixelsCap) {
inSampleSize++;
}
}
return inSampleSize;
}
}
Bitmap减小占用字节
A:透明度 R:红色 G:绿 B:蓝
Bitmap.Config ARGB_4444:每个像素占四位,共16位
Bitmap.Config ARGB_8888:每个像素占四位,共32位
Bitmap.Config RGB_565:每个像素占四位,共16位
Bitmap.Config ALPHA_8:每个像素占四位,只有透明度,没有颜色。
//设置图片像素格式
BitmapFactory.Options options = new BitmapFactory.Options();
// 默认是Bitmap.Config.ARGB_8888
options.inPreferredConfig = Bitmap.Config.ARGB_4444;
BitmapFactory.decodeResources(getResources(),mImgId,options);
LRU cache
- 初始化
ActivityManager am=(ActivityManager)getSystemService(Context.ACTIVITY_SERVICE);
int availMernlnBytes=am.getMemoryClass()*1024*1024;
LruCache bitmapCache=new LruCache<String,Bitmap>(availMernlnBytes/8);
- 指定插入数据的大小
public class ThumbnailCache extends LruCache(String,Bitmap){
@Override
protected int sizeOf(String key,Bitmap value){
return value.getByteCount();
}
}
- 实现
Bitmap map=mCache.get(fileName);
if(map==null){
map=BitmapFactory.decodeFile(fileName);
mCache.put(fileName,map);
}
ActivityManager am=(ActivityManager)getSystemService(Context.ACTIVITY_SERVICE);
int availMernlnBytes=am.getMemoryClass()*1024*1024;
LruCache bitmapCache=new LruCache<String,Bitmap>(availMernlnBytes/8);
public class ThumbnailCache extends LruCache(String,Bitmap){
@Override
protected int sizeOf(String key,Bitmap value){
return value.getByteCount();
}
}
Bitmap map=mCache.get(fileName);
if(map==null){
map=BitmapFactory.decodeFile(fileName);
mCache.put(fileName,map);
}