Light

Project Url: JavaNoober/Light
Introduction: a lightweight image compress framework for Android based on libjpeg
More: Author   ReportBugs   
Tags:

license JCenter

a lightweight image compress framework for Android based on libJpeg. 一个基于 libJpeg 的压缩图片框架, 支持配合 rxjava 使用。

说明

这个库主要是用于压缩图片体积,当然也可以压缩 bitamp 减少内存。但是在显示需要高清晰度的图片的时候,比如 icon,背景图,建议还是使用 glide picasso 等成熟的框架,而需要保存图片文件的时候使用本框架。
如果需要对 icon 背景图等图片压缩可以通过这个网址: https://tinypng.com/

demo 效果

先展示一下压缩前后的效果对比,以及文件大小和占用内存的大小 demo 比较简单,运行的时候请打开 sd 卡权限和相册拍照权限。

基本功能:

支持的压缩类型: File,String,Uri,Bytes,Bitmap,DrawableResourceID,Drawable

  • 1:图片的旋转、缩放、平移操作
  • 2:异步和同步压缩处理
  • 3:同步压缩
  • 4:可以配合 RxJava2 使用

    版本记录:

    1.0.0 完成大致功能
    1.1.0 修复从 uri 获取路径错误的 bug;
          增加 ignoreSize 的设置,以便用于压缩图片保持原尺寸;
          支持配合 rxjava2 使用;
    1.1.1 优化异常提示;
    1.1.2 增加 Light.getInstance().compressFromHttp 方法,从网络获取图片;      
    1.1.3 RxLight 去除线程切换控制,让开发者自己去指定线程;
          去掉无用类;
    1.1.4 增加 autoRotation 的设置(只有压缩从本地读取图片有用,其他情况无效),可以将图片自动旋转为 0 度, 便于解决三星手机拍照会自动将图片选择的问题;
    1.1.5 优化部分代码,解决 bug;
          增加 autoRecycle 的设置(只有压缩 bitmap 和压缩 byte 类型的图片有用,其他类型图片无效),开启该设置代表自动会将传入的 bitmap 或者 bytes 进行内存回收;
    1.1.6 增加 compressFileSize 的压缩设置,可以设置当大于一定 kb 大小的图片,才会进行压缩,只对压缩保存到本地的方法有效,对压缩保存到 bitmap 的方法无效;
    1.1.7 默认对 gif 不支持压缩
    1.1.9 修复 bug
    1.2.0 增加 Bitmap.Config 的设置,默认是 RGB_565,可以在 CompressArgs 设置,也可以在 LightConfig 统一配置
    1.2.1 网络图片下载增加磁盘缓存
    1.2.2 增加 arm64-v8a 的支持
    

    使用方法:

     android {
         ...
         ndk {
             abiFilters 'armeabi-v7a', 'armeabi'
             //abiFilters 'armeabi-v7a', 'armeabi', 'arm64-v8a' 根据需要选择指令集架构
         }
     }
    
     //引入
     implementation 'com.noober.light:core:1.2.2'
    
     //如果要配合 rxjava2,加入 rxjava2 的依赖
     implementation 'io.reactivex.rxjava2:rxandroid:2.0.1'
     implementation 'io.reactivex.rxjava2:rxjava:2.1.7'
    

设置压缩参数:

CompressArgs 这个类用于设置每次所要压缩到的指定的宽高以及压缩质量。使用如下:

CompressArgs args = new CompressArgs.Builder().width(width).height(height).quality(70).ignoreSize(false).build();
参数说明:

1.width: 要压缩到的图片的宽度,单位 px
2.height: 要压缩到的图片的高度,单位 px
3.quality: 压缩质量, 可选范围是 0-100。
4.ignoreSize: 是否要忽略压缩后图片宽高的限制, 如果设为 true,压缩的时候会根据原图本身大小进行压缩,设置的 width 和 height 就会失效,默认 false。 5.autoRotation: 是否要将图片自动摆正,只有压缩从本地读取图片有用,其他情况无效(例如三星手机拍照后图片会自动旋转,设为 true 则会自动将图片旋转正确的方向)。
6.autoRecycle: 是否需要自动将传入的 bitmap 或者 bytes 进行内存回收,只有压缩 bitmap 和压缩 byte 类型的图片有用,其他类型图片无效
7.compressFileSize: 对压缩图片到本地的时候增加文件大小的设置,如果大于此 kb 大小的图片,则不进行压缩。
8.bitmapConfig: 设置 bitmap 的色彩模式,默认是 RGB_565
因为从网络下载图片保存到本地,中间默认会自动压缩图片,如果不想对图片进行压缩,并保持宽高的话,设置如下参数即可:

CompressArgs args = new CompressArgs.Builder().quality(100).ignoreSize(true).autoRotation(true)
.autoRecycle(true).bitmapConfig(Bitmap.Config.ARGB_8888).build();
默认参数:

调用 compress 方法的时候也可以不初始化这个参数,框架会自动初始化一个默认的压缩设置。

默认规则如下: 压缩图片的最大默认高度是屏幕高度; 图片的最大宽度是屏幕宽度; 默认压缩质量是 85; ignoreSize 为 false。

设置全局的压缩参数,以便不需要每次都去设置:

建议在 Application 的 onCreate 中进行初始化,使用如下:

LightConfig lightConfig = new LightConfig();
lightConfig.setDefaultQuality(xx);
lightConfig.setMaxWidth(xx);
lightConfig.setMaxHeight(xx);
lightConfig.setMaxHeight(xx);
lightConfig.setNeedIgnoreSize(xx);
...
Light.getInstance().setConfig(lightConfig);

压缩图片,获取 Bitmap:images -> Bitmap

支持File,String,Uri,Bytes,Bitmap,DrawableResourceID,Drawable这 5 种类型压缩为 Bitmap。

//String,Uri,Bytes,Bitmap,File -->bitmap
Bitmap bitmap = Light.getInstance().compress(path);
//args 为 CompressArgs 压缩参数,不传入,即用默认参数
Bitmap bitmap = Light.getInstance().compress(path, args);
.....

压缩图片并且保存到本地:images -> boolean

支持File,String,Uri,Bytes,Bitmap这 5 种类型保存为文件。 想对于压缩成 Bitmap 的方法只是多了一个输出路径。

//images --> boolean //保存图片,返回值代表保存是否成功
//img 为要压缩的图片,args 是压缩参数,不传即默认, outPath 为输出路径
Light.getInstance().compress(img, args, outPath);
Light.getInstance().compress(img, outPath);
//支持类型 Bitmap, Bytes, String, Resource, Uri, Drawable

从网络获取图片

注意,onCompressFinishListener 必须实现,否则会不进行下载,onCompressFinishListener 必须实现接口返回值是 byte,可以用来保存到 file, openDiskCache 若为 true 则开启图片缓存

    Light.getInstance().compressFromHttp(uri, openDiskCache, new OnCompressFinishListener() {
        @Override
        public void onFinish(byte[] bytes) {
            Bitmap bitmap = Light.getInstance().compress(bytes);
            ...
        }
    });

配合 RxJava2 使用

关于配合 RxJava2 使用的类都在 RxLight 这个类中。 通过与 rxJava 的配合,一行代码就能实现从网络下载->压缩->显示,这个过程,非常的方便。

使用方法如下:

RxLight 会自动对图片进行下载 -> 压缩 -> 显示或保存到本地

从网络获取资源 -> Bitmap:
RxLight.compressForUriHttp()中参数 openDiskCache 控制是否增加磁盘缓存

//uri 类型的网络资源
Flowable.just(uri).compose(RxLight.compressForUriHttp()).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(bitmap -> ivCompress.setImageBitmap(bitmap));
List<Uri> urlList = new ArrayList<>();
....
Flowable.fromIterable(urlList).compose(RxLight.compressForUriHttp()).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(bitmap -> ivCompress.setImageBitmap(bitmap));
//url 类型的网络资源
Flowable.just(url).compose(RxLight.compressForStringHttp()).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(bitmap -> ivCompress.setImageBitmap(bitmap));
List<String> urlList = new ArrayList<>();
....
Flowable.fromIterable(urlList).compose(RxLight.compressForStringHttp()).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(bitmap -> ivCompress.setImageBitmap(bitmap));
//或者传入自定义的压缩参数只需要在 compressForUriHttp() 和 compressForStringHttp()传入 CompressArgs 即可
CompressArgs args = new CompressArgs();
....
Flowable.just(uri).compose(RxLight.compressForUriHttp(args)).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(bitmap -> ivCompress.setImageBitmap(bitmap));
从网络获取资源 -> boolean(保存到本地):

与上述方法类似,只需要 compressForUri() 和 compressForString()传入要保存到的路径即可。同样支持 uri 和 string 的网络地址类型。

RxLight.compressForUriHttp(中参数 openDiskCache 控制是否增加磁盘缓存, path)中参数 openDiskCache 控制是否增加磁盘缓存
String path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/pic.jpg";
Flowable.just(uri).compose(RxLight.compressForUriHttp(path)).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(result -> {});
//自定义压缩参数
CompressArgs args = new CompressArgs();
....
Flowable.just(uri).compose(RxLight.compressForUriHttp(path, args)).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(result -> {});
通过本地资源异步压缩

同样都支持 File,String,Uri,Bytes,Bitmap,DrawableResourceID,Drawable 这几种类型

图片资源 -> Bitmap

通过 RxLight.compress()方法即可:

Flowable.just(image).compose(RxLight.compress()).subscribe(bitmap -> ivCompress.setImageBitmap(bitmap));
图片资源 -> Boolean(保存到本地):

通过 RxLight.compress(outPath)方法即可:

Flowable.just(image).compose(RxLight.compress(outPath)).subscribe(bitmap -> ivCompress.setImageBitmap(bitmap));

其他

  • 1:MemoryComputeUtil 工具类,获取 bitmap 占用内存的大小,返回值单位是 kb。
     MemoryComputeUtil.getMemorySize(compressBitmap)
    Bitmap result = new MatrixUtil.Build().scale(scaleSize, scaleSize).rotate(90f).bitmap(bitmap).build();

总结

版本还在逐步更新中,欢迎各位大佬 star,以及提出建议。

GitHub demo 下载地址:https://github.com/JavaNoober/Light

Apps
About Me
Google+: Trinea trinea
GitHub: Trinea