ImageLoader
图片加载框架的 api 封装
特点
- api 设计参考 glide,链式调用
- 目前底层依赖 fresco 和 glide,picasso,直接 gradle 改一下就切换了
- 能够以同样 api 获取 bitmap,所设置的宽高,高斯模糊,圆角或圆形效果均生效.
- 解决了 fresco 最新版中,获取到的 bitmap 是 recycled,不能用的问题
- 基于 subsampling-scale-image-view 的大图预览功能,带进度和失败状态,能轮播,极致的高清无码,更重要的是非常省内存,绝不泄漏
- 丰富便捷的 api: 暂停和继续图片加载,获取磁盘缓存大小和清空缓存,响应内存事件等等.
- 可以设置 placeHolder,loadingDrawable,errorHolder,并且均可以自定义其 scaleType.
TODO
- 自动识别 gif 并加载
- 适配 wrap_centent
- 适配 focus_face
com.github.hss01248.ImageLoader:MediaStoreApi:3.4.7
com.github.hss01248.ImageLoader:imageloader:3.4.7
com.github.hss01248.ImageLoader:avif:3.4.7
com.github.hss01248.ImageLoader:compressor:3.4.7
com.github.hss01248.ImageLoader:fileOperation:3.4.7
com.github.hss01248.ImageLoader:frescoGlideBridge:3.4.7
com.github.hss01248.ImageLoader:avif-decoder:3.4.7
com.github.hss01248.ImageLoader:downloader:3.4.7
com.github.hss01248.ImageLoader:imageDebugger:3.4.7
com.github.hss01248.ImageLoader:baseWebview:3.4.7
com.github.hss01248.ImageLoader:glidebase:3.4.7
com.github.hss01248.ImageLoader:bigimageviewpager:3.4.7
com.github.hss01248.ImageLoader:webviewspider:3.4.7
com.github.hss01248.ImageLoader:glidev4:3.4.7
com.github.hss01248.ImageLoader:imagelist:3.4.7
一条龙地支持 fresco 和 glide
图片加载:ImageLoader -->> 图片选择: PhotoPicker -->>拍照/选图/裁剪/压缩: PhotoOut
效果图:
优化缓存文件大小
图片下载完成后,给它压缩成 webp,然后替换调原缓存文件, 小尺寸的图也换成 webp
更新日志
https://raw.githubusercontent.com/hss01248/ImageLoader/master/LOG.md
public interface ILoader {
void init(Context context,int cacheSizeInM);//初始化
void request(SingleConfig config);//核心方法,仅供内部调用
//图片加载的暂停和继续
void pause();
void resume();
//缓存大小与清除
void clearDiskCache();
void clearMomoryCache();
long getCacheSize();
//下面是操作磁盘缓存的一些方法(glide 无法同步获取,fresco 可以)
void clearCacheByUrl(String url);
File getFileFromDiskCache(String url);
boolean isCached(String url);
//下面是内存的优化-响应 app 的内存事件,做出相应的处理
void trimMemory(int level);
void clearAllMemoryCaches();
}
初始化
Application 中:
oncreate 方法中:
传入全局 context 和定义缓存文件夹的大小
init(final Context context, int cacheSizeInM,ILoader loader)//指定缓存大小,以及使用哪个 loader
响应 app 的内存事件,预防 OOM:
@Override
public void onTrimMemory(int level) {
super.onTrimMemory(level);
ImageLoader.trimMemory(level);
}
@Override
public void onLowMemory() {
super.onLowMemory();
ImageLoader.clearAllMemoryCaches();
}
入口方法
该方法返回 SingleConfig.ConfigBuilder
ImageLoader.with(this)
自定义设置
几种不同的图片源
.url(String url)
.file(String filePath)
.res(int resId)
.content(String contentProvider)
https 时是否忽略证书校验
默认不忽略
.ignoreCertificateVerify(boolean ignoreCertificateVerify)
传入宽高,用于 resize,以节省内存(必传参数)
一般,传如用于显示的那个 view 的宽高就行,单位为 dp.内部会自行转换为 px
框架能根据这两个参数去把图片流解压成这个大小的 bitmap,可以节约内存空间
widthHeight(int width,int height)
占位图/默认图
本方法的生效规则: 当容器 view 可复用(在 recycleview,或者可复用的 viewpager 中)时,一定会设置占位图,否则会出现两幅实际图片快速切换闪烁的情况 当容器 view 不复用时,当且仅当图片源为网络图片且本地没有缓存时,才会设置 placeholder.以避免 placehoder 和正式图片的快速切换闪烁
placeHolder(int placeHolderResId,boolean reuseable)
error 图
error(int errorResId)
圆角矩形
可以设置圆角的半径,以及当图片是 gif 动图时,用什么颜色来盖一层,以实现动图时的圆角
rectRoundCorner(int rectRoundRadius,int overlayColorWhenGif)
设置图片为圆形
asCircle(int overlayColorWhenGif)
图片的边框(glide 不支持)
border(int borderWidth,int borderColor)
缩放模式
参考 fresco 的模式设置,取值为 ScaleMode.xxx.
这个模式只会改变 bitmap 展示在 view 上面的模式,而不会改变 bitmap 在内存中的大小
scale(int scaleMode)
类型 | 描述 |
---|---|
center | 居中,无缩放。 |
centerCrop | 保持宽高比缩小或放大,使得两边都大于或等于显示边界,且宽或高契合显示边界。居中显示。 |
focusCrop | 同 centerCrop, 但居中点不是中点,而是指定的某个点。 |
centerInside | 缩放图片使两边都在显示边界内,居中显示。和 fitCenter 不同,不会对图片进行放大。如果图尺寸大于显示边界,则保持长宽比缩小图片。 |
fitCenter | 保持宽高比,缩小或者放大,使得图片完全显示在显示边界内,且宽或高契合显示边界。居中显示。 |
fitStart | 同上。但不居中,和显示边界左上对齐。 |
fitEnd | 同 fitCenter, 但不居中,和显示边界右下对齐。 |
fitXY | 不保存宽高比,填充满显示边界。 |
配置高斯模糊
传入的参数 blurRadius 为模糊度,越大就越模糊,实际效果要自己调试好相应的数字
blur(int blurRadius)
最终的出口方法有两个
显示到某一个 view 中
into(View targetView)
或者,只拿 bitmap 引用
此时,scale 的配置是无效的,因为没有 view 去给它展示. 而其他设置的宽高,高斯模糊,圆角或圆形效果,都能生效,最终给你一个你想要的 bitmap
asBitmap(BitmapListener bitmapListener)
加载大图
内部采用的是 https://github.com/davemorrissey/subsampling-scale-image-view
加载单张大图:
ImageLoader.loadBigImage(BigImageView imageView,String path)
//说明: path 可以是网络 url,文件路径或者 content://格式的路径
当是网络 url 时,注意应该以 http 开头,这里内部不提供拼接功能
内置了 placeholder,progressbar,errorview.
加载多张大图:
用户只需要传入单纯的 viewPager 对象,框架会替调用者设置好特定的 adapter.
pageradapter 内部只构建 4 个 BigImageView,滑动时复用此 view,则对应的 bitmap 能够被不断回收.
ImageLoader.loadBigImages(ViewPager viewPager, List<String> urls)//urls 或 filepaths
之前 BigImageView 有内存泄漏时,.几十张超级大图(4000*3000 像素左右),快速滑动和快速缩放时,内存占用偶尔冲上五六十 M,但很快会降到 40M 左右,关掉 activity 内存一直不下,解决内存泄漏后,十分清爽:
前一次的 activity 泄漏:多次进出,基线维持在 40M 水平
解决了内存泄漏后:20M 左右
注意,如果是使用 Picasso,请在 viewpager 所在的 activity 的 ondestroy 方法中调用:(清除磁盘缓存)
PicassoBigLoader.clearCache()
内存优化的几个策略的说明
bitmap 编码
将 fresco 框架默认的 RGB_888 改成 RGB_565,每张图片内存能减小一半,而显示效果相差并不大.
初始化时 ImagePipelineConfig 设置 setBitmapsConfig(Bitmap.Config.RGB_565)
downsampling 和 resization 配合
图片向下采样,将图片采样成设定的宽高的 bitmap,而不是加载原图.
初始化时 ImagePipelineConfig.Builder 设置 setDownsampleEnabled(true)//同时支持 PNG,JPG 以及 WEP 格式的图片
每次加载图片时,指定宽高,即可执行 resization,将图片解析成该宽高的 bitmap.
预防 OOM
自定义控制 fresco 的内存对象池大小
初始化时 ImagePipelineConfig.Builder 设置 setBitmapMemoryCacheParamsSupplier(new MyBitmapMemoryCacheParamsSupplier(activityManager))
并且响应 app 的内存事件,在内存不够时进行清除内存缓存.
Application 的回调中调用方法:
@Override
public void onTrimMemory(int level) {
super.onTrimMemory(level);
ImageLoader.trimMemory(level);
}
@Override
public void onLowMemory() {
super.onLowMemory();
ImageLoader.clearAllMemoryCaches();
}
外部辅助
如果图片用的是七牛云存储或者阿里云,那么利用他们的图片处理的 api,请求时带上目标宽高等参数,让他们裁剪成你要的小图后返回,不仅省内存,而且省流量.
示例代码:
ImageLoader.with(this)
.url("https://pic1.zhimg.com/v2-7868c606d6ddddbdd56f0872e514925c_b.jpg")
.placeHolder(R.mipmap.ic_launcher)
.widthHeight(250,150)
.asCircle(R.color.colorPrimary)
.into(ivUrl);
ImageLoader.with(this)
.placeHolder(R.mipmap.ic_launcher)
.res(R.drawable.thegif)
.widthHeight(250,150)
.rectRoundCorner(15,R.color.colorPrimary)
.asBitmap(new SingleConfig.BitmapListener() {
@Override
public void onSuccess(Bitmap bitmap) {
Log.e("bitmap",bitmap.getWidth()+"---height:"+bitmap.getHeight()+"--"+bitmap.toString());
}
@Override
public void onFail() {
Log.e("bitmap","fail");
}
});
usage
gradle
Step 1. Add the JitPack repository to your build file
Add it in your root build.gradle at the end of repositories:
allprojects {
repositories {
...
maven { url "https://jitpack.io" }
}
}
Step 2. Add the dependency( 三选一即可)
dependencies {
compile 'com.github.hss01248.ImageLoader:fresco:1.0.8'//如果使用 fresco
compile 'com.github.hss01248.ImageLoader:glide:1.0.8'//如果使用 glide
compile 'com.github.hss01248.ImageLoader:picasso:1.0.8'//如果使用 picasso
}
脸部识别
因为耗时长,需要依赖 com.google.android.gms:play-services,国内阉割版 rom 用不了.
所以没有引入到包中,但已预留相关接口
需要的自行打开那一行代码注释即可试用
https://github.com/aryarohit07/GlideFaceDetectionTransformation
https://github.com/aryarohit07/PicassoFaceDetectionTransformation
https://github.com/aryarohit07/FrescoFaceDetectionProcessor
thanks
https://github.com/facebook/fresco
https://github.com/Piasy/BigImageViewer
https://github.com/AlexMofer/RecyclePagerAdapter
bitmap 转换器:
https://github.com/wasabeef/fresco-processors
https://github.com/wasabeef/glide-transformations
https://github.com/wasabeef/picasso-transformations
extend:
https://github.com/JakeWharton/picasso2-okhttp3-downloader