Bitmap的基本概念
- Bitmap意为位图,是Android系统中的图像处理的最重要的类之一。
- 通过Bitmap我们可以获取图片的相关信息
- 获取到信息以后,可以对其进行缩放,裁剪等操作
Bitmap为我们提供了对于图像文件的操作
加载方法
Bitmap有4种加载方法:
1、字节数组:BitmapFactory.decodeByteArray()
2、文件路径:BitmapFactory.decodeFile()
3、资源ID:BitmapFactory.decodeResource()
4、流:BitmapFactory.decodeStream()
为什么要高效加载
- 防止内存溢出
- 尽可能的节省内存开销
- 使得APP更加流畅
BitmapFactory.Options
属性:
- inJustDecodeBounds 标志位,是要加载图片,还是获取图片相关信息
- outWidth&outHeight 宽高
- inSampleSize 采样率
所以我们使用这个类的这几个属性来进行图片的裁剪:
package com.gin.xjh.bitmap;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
public class BitmapUtil {
public static Bitmap ratio(String filePath, int piexlW, int piexlH) {
BitmapFactory.Options newOptions = new BitmapFactory.Options();
newOptions.inJustDecodeBounds = true;
newOptions.inPreferredConfig = Bitmap.Config.RGB_565;//压缩质量参数
//预加载
BitmapFactory.decodeFile(filePath, newOptions);
int originalW = newOptions.outWidth;
int originalH = newOptions.outHeight;
newOptions.inSampleSize = getSimpleSize(originalW, originalH, piexlW, piexlH);
newOptions.inJustDecodeBounds = false;
return BitmapFactory.decodeFile(filePath, newOptions);
}
private static int getSimpleSize(int originalW, int originalH, int piexlW, int piexlH) {
int simpkeSize = 1;
if (originalW > originalH && originalW > piexlW) {
simpkeSize = originalW / piexlW;
} else if (originalW < originalH && originalH > piexlH) {
simpkeSize = originalH / piexlH;
}
if (simpkeSize <= 0) {
simpkeSize = 1;
}
return simpkeSize;
}
}
缓存
我们还有高效的加载的方法就是使用缓存,因为很多的图片是重复加载的,原来加载过的,所以我们可以去使用缓存机制来进行高效的加载
缓存的优势
- 对一些不是经常更新的数据可以使用本地缓存,提升应用响应速度
- 我们使用缓存就可以不用再频繁的请求服务器,可以降低服务器的负载压力
我们可以使用的缓存策略在Android中主要有下面三种
- LruCache 实现内存缓存(在一些情况下会进行清除,如:内存不足)
- DiskLruCache 实现硬盘缓存(外置存储中)
- SQLite实现缓存(存储在数据库中)
LruCache
Lru是一种缓存算法,最近最少使用算法,LruCache采用的是LinkedHashMap。
使用LruCache实现网络图片缓存:
package com.gin.xjh.bitmap;
import android.graphics.Bitmap;
import android.util.LruCache;
import android.widget.ImageView;
public class SimpleImageLoader {
private static SimpleImageLoader mLoader = null;
private LruCache<String, Bitmap> mLruCache;
public static SimpleImageLoader getInstance() {
if (mLoader == null) {
synchronized (SimpleImageLoader.class) {
if (mLoader == null) {
mLoader = new SimpleImageLoader();
}
}
}
return mLoader;
}
/**
* 初始化缓存对象
*/
private SimpleImageLoader() {
int maxSize = (int) (Runtime.getRuntime().maxMemory() / 8);
mLruCache = new LruCache<String, Bitmap>(maxSize) {
@Override
protected int sizeOf(String key, Bitmap value) {
return value.getByteCount();
}
};
}
/**
* 加载网络图片
*/
public void displayImage(ImageView view, String url) {
Bitmap bitmap = getBitmapFromCache(url);
if (bitmap != null) {
view.setImageBitmap(bitmap);
} else {
downloadImage(view, url);
}
}
/**
* 从缓存中读取图片
*/
private Bitmap getBitmapFromCache(String url) {
return mLruCache.get(url);
}
/**
* 将下载下来的图片保存到缓存中
*/
private void putBitmapToCache(Bitmap bitmap, String url) {
if (bitmap != null) {
mLruCache.put(url, bitmap);
}
}
/**
* 下载图片,并且加载到缓存中
*/
private void downloadImage(final ImageView imageView, final String url) {
//进行图片的网络下载功能
//在图片下载成功后调用
Bitmap bitmap = null;
putBitmapToCache(bitmap, url);
}
}
对于图片从网络上下载下来的代码我就不写了,可以使用网上的很多网络请求的开源库,或者直接使用Android中自带的HttpURLConnection进行下载(如果不会使用可以看我上一篇博客:传送门)
DiskLruCache
这个是由square团队开发的第三方的开源库,GitHub地址:https://github.com/JakeWharton/DiskLruCache
我们如何进行DiskLruCache的使用呢:
- 通过DiskLruCache.open去初始化一个缓存对象
- 通过DiskLruCache.get(String key)去获取到对应key下的缓存数据
- 通过DiskLruCache.Editor对象将数据保存到本地
并且因为DiskLruCache是放在外置存储中的,所以我们对于缓存路径要进行设置:
- 有SDCard:
/sdcard/Android/data/<application package>/cache
- 无SDCard:
/data/data/Android/data/<application package>/cache
这样的路径的原因是保证在APP下载后不会残留缓存文件在内存中。
GitHub地址:传送门