终极图片压缩
图片优化压缩方式大概可以分为以下几类:更换图片格式,质量压缩,采样率压缩,缩放压缩,调用jpeg压缩等
1、设置图片格式
Android目前常用的图片格式有png,jpeg和webp,
png:无损压缩图片格式,支持Alpha通道,Android切图素材多采用此格式
jpeg:有损压缩图片格式,不支持背景透明,适用于照片等色彩丰富的大图压缩,不适合logo
webp:是一种同时提供了有损压缩和无损压缩的图片格式,派生自视频编码格式VP8,从谷歌官网来看,无损webp平均比png小26%,有损的webp平均比jpeg小25%~34%,无损webp支持Alpha通道,有损webp在一定的条件下同样支持,有损webp在Android4.0(API 14)之后支持,无损和透明在Android4.3(API18)之后支持
采用webp能够在保持图片清晰度的情况下,可以有效减小图片所占有的磁盘空间大小
2、质量压缩
质量压缩并不会改变图片在内存中的大小,仅仅会减小图片所占用的磁盘空间的大小,因为质量压缩不会改变图片的分辨率,而图片在内存中的大小是根据widthheight一个像素的所占用的字节数计算的,宽高没变,在内存中占用的大小自然不会变,质量压缩的原理是通过改变图片的位深和透明度来减小图片占用的磁盘空间大小,所以不适合作为缩略图,可以用于想保持图片质量的同时减小图片所占用的磁盘空间大小。另外,由于png是无损压缩,所以设置quality无效,以下是实现方式:
/**
* 质量压缩 bitmap.compress
*
* @param format 图片格式 jpeg,png,webp
* @param quality 图片的质量,0-100,数值越小质量越差
*/
public static void compress(Bitmap.CompressFormat format, int quality) {
File sdFile = Environment.getExternalStorageDirectory();
File originFile = new File(sdFile, "originImg.jpg");
Bitmap originBitmap = BitmapFactory.decodeFile(originFile.getAbsolutePath());
ByteArrayOutputStream bos = new ByteArrayOutputStream();
originBitmap.compress(format, quality, bos);
try {
FileOutputStream fos = new FileOutputStream(new File(sdFile, "resultImg.jpg"));
fos.write(bos.toByteArray());
fos.flush();
fos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
3、采样率压缩
采样率压缩是通过设置BitmapFactory.Options.inSampleSize,来减小图片的分辨率,进而减小图片所占用的磁盘空间和内存大小。
设置的inSampleSize会导致压缩的图片的宽高都为1/inSampleSize,整体大小变为原始图片的inSampleSize平方分之一,当然,这些有些注意点:
1、inSampleSize小于等于1会按照1处理
2、inSampleSize只能设置为2的平方,不是2的平方则最终会减小到最近的2的平方数,如设置7会按4进行压缩,设置15会按8进行压缩。
具体的代码实现方式如下:
/**
*
* @param inSampleSize 可以根据需求计算出合理的inSampleSize
*/
public static void compress(int inSampleSize) {
File sdFile = Environment.getExternalStorageDirectory();
File originFile = new File(sdFile, "originImg.jpg");
BitmapFactory.Options options = new BitmapFactory.Options();
//设置此参数是仅仅读取图片的宽高到options中,不会将整张图片读到内存中,防止oom
options.inJustDecodeBounds = true;
Bitmap emptyBitmap = BitmapFactory.decodeFile(originFile.getAbsolutePath(), options);
options.inJustDecodeBounds = false;
options.inSampleSize = inSampleSize;
Bitmap resultBitmap = BitmapFactory.decodeFile(originFile.getAbsolutePath(), options);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
resultBitmap.compress(Bitmap.CompressFormat.JPEG, 100, bos);
try {
FileOutputStream fos = new FileOutputStream(new File(sdFile, "resultImg.jpg"));
fos.write(bos.toByteArray());
fos.flush();
fos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
4.框架实现的效果:
4.1 设置压缩配置参数
compressConfig = CompressConfig.builder()
.setUnCompressMinPixel(1000) // 最小像素不压缩,默认值:1000
.setUnCompressNormalPixel(2000) // 标准像素不压缩,默认值:2000
.setMaxPixel(1000) // 长或宽不超过的最大像素 (单位px),默认值:1200
.setMaxSize(100 * 1024) // 压缩到的最大大小 (单位B),默认值:200 * 1024 = 200KB
.enablePixelCompress(true) // 是否启用像素压缩,默认值:true
.enableQualityCompress(true) // 是否启用质量压缩,默认值:true
.enableReserveRaw(true) // 是否保留源文件,默认值:true
.setCacheDir("") // 压缩后缓存图片路径,默认值:Constants.COMPRESS_CACHE
.setShowCompressDialog(true) // 是否显示压缩进度条,默认值:false
.create();
4.2 多图压缩
private void compressMore() {
// 测试多张图片同时压缩
ArrayList<Photo> photos = new ArrayList<>();
photos.add(new Photo("/storage/emulated/0/DCIM/Camera/IMG_20171108_151541.jpg"));
photos.add(new Photo("/storage/emulated/0/DCIM/Camera/IMG_20171011_095724.jpg"));
photos.add(new Photo("/storage/emulated/0/DCIM/Camera/IMG_20171011_092207.jpg"));
photos.add(new Photo("/storage/emulated/0/DCIM/Camera/IMG_20170608_113509.jpg"));
photos.add(new Photo("/storage/emulated/0/tencent/MicroMsg/WeiXin/mmexport1535449679877.jpg"));
photos.add(new Photo("/storage/emulated/0/autoLite/cameraImg/1535016551150.jpg"));
photos.add(new Photo("/storage/emulated/0/Download/微信图片_20171205095927.jpg"));
photos.add(new Photo("/storage/emulated/0/Pictures/camera_20181115_111332.jpg"));
photos.add(new Photo("/storage/emulated/0/Pictures/camera_20180706_173207.jpg"));
compress(photos);
}
// 开始压缩
private void compress(ArrayList<Photo> photos) {
if (compressConfig.isShowCompressDialog()) {
Log.e("netease >>> ", "开启了加载框");
dialog = CommonUtils.showProgressDialog(this, "压缩中……");
}
CompressImageManager.build(this, compressConfig, photos, this).compress();
}
4.3 压缩完回调
@Override
public void onCompressSuccess(ArrayList<Photo> arrayList) {
Log.e("netease >>> ", "压缩成功");
if (dialog != null && !isFinishing()) {
dialog.dismiss();
}
}
@Override
public void onCompressFailed(ArrayList<Photo> arrayList, String error) {
Log.e("netease >>> ", error);
if (dialog != null && !isFinishing()) {
dialog.dismiss();
}
}
代码解析:
通过建造者配置压缩参数:
import java.io.Serializable;
/**
* 压缩配置类
*/
public class CompressConfig implements Serializable {
/**
* 最小像素不压缩
*/
private int unCompressMinPixel = 1000;
/**
* 标准像素不压缩
*/
private int unCompressNormalPixel = 2000;
/**
* 长或宽不超过的最大像素,单位px
*/
private int maxPixel = 1200;
/**
* 压缩到的最大大小,单位B
*/
private int maxSize = 200 * 1024;
/**
* 是否启用像素压缩
*/
private boolean enablePixelCompress = true;
/**
* 是否启用质量压缩
*/
private boolean enableQualityCompress = true;
/**
* 是否保留源文件
*/
private boolean enableReserveRaw = true;
/**
* 压缩后缓存图片目录,非文件路径
*/
private String cacheDir;
/**
* 是否显示压缩进度条
*/
private boolean showCompressDialog;
public static CompressConfig getDefaultConfig() {
return new CompressConfig();
}
private CompressConfig() {
}
public int getUnCompressMinPixel() {
return unCompressMinPixel;
}
private void setUnCompressMinPixel(int unCompressMinPixel) {
this.unCompressMinPixel = unCompressMinPixel;
}
public int getUnCompressNormalPixel() {
return unCompressNormalPixel;
}
private void setUnCompressNormalPixel(int unCompressNormalPixel) {
this.unCompressNormalPixel = unCompressNormalPixel;
}
public int getMaxPixel() {
return maxPixel;
}
private void setMaxPixel(int maxPixel) {
this.maxPixel = maxPixel;
}
public int getMaxSize() {
return maxSize;
}
private void setMaxSize(int maxSize) {
this.maxSize = maxSize;
}
public boolean isEnablePixelCompress() {
return enablePixelCompress;
}
private void setEnablePixelCompress(boolean enablePixelCompress) {
this.enablePixelCompress = enablePixelCompress;
}
public boolean isEnableQualityCompress() {
return enableQualityCompress;
}
private void setEnableQualityCompress(boolean enableQualityCompress) {
this.enableQualityCompress = enableQualityCompress;
}
public boolean isEnableReserveRaw() {
return enableReserveRaw;
}
private void setEnableReserveRaw(boolean enableReserveRaw) {
this.enableReserveRaw = enableReserveRaw;
}
public String getCacheDir() {
return cacheDir;
}
public void setCacheDir(String cacheDir) {
this.cacheDir = cacheDir;
}
public boolean isShowCompressDialog() {
return showCompressDialog;
}
private void setShowCompressDialog(boolean showCompressDialog) {
this.showCompressDialog = showCompressDialog;
}
public static Builder builder() {
return new Builder();
}
public static class Builder {
private CompressConfig config;
private Builder() {
config = new CompressConfig();
}
public Builder setUnCompressMinPixel(int unCompressMinPixel) {
config.setUnCompressMinPixel(unCompressMinPixel);
return this;
}
public Builder setUnCompressNormalPixel(int unCompressNormalPixel) {
config.setUnCompressNormalPixel(unCompressNormalPixel);
return this;
}
public Builder setMaxSize(int maxSize) {
config.setMaxSize(maxSize);
return this;
}
public Builder setMaxPixel(int maxPixel) {
config.setMaxPixel(maxPixel);
return this;
}
public Builder enablePixelCompress(boolean enablePixelCompress) {
config.setEnablePixelCompress(enablePixelCompress);
return this;
}
public Builder enableQualityCompress(boolean enableQualityCompress) {
config.setEnableQualityCompress(enableQualityCompress);
return this;
}
public Builder enableReserveRaw(boolean enableReserveRaw) {
config.setEnableReserveRaw(enableReserveRaw);
return this;
}
public Builder setCacheDir(String cacheDir) {
config.setCacheDir(cacheDir);
return this;
}
public Builder setShowCompressDialog(boolean showCompressDialog) {
config.setShowCompressDialog(showCompressDialog);
return this;
}
public CompressConfig create() {
return config;
}
}
}
压缩封装整合:对压缩的集合进行递归压缩,压缩完回调
import android.content.Context;
import android.text.TextUtils;
import com.netease.image.library.bean.Photo;
import com.netease.image.library.config.CompressConfig;
import com.netease.image.library.core.CompressImageUtil;
import com.netease.image.library.listener.CompressImage;
import com.netease.image.library.listener.CompressResultListener;
import java.io.File;
import java.util.ArrayList;
/**
* 框架:思路、起稿。千万不要过度封装
* 压缩图片管理类
* 1、单例?
* 2、能否重复压缩?
*/
public class CompressImageManager implements CompressImage {
private CompressImageUtil compressImageUtil; // 压缩工具类
private ArrayList<Photo> images; // 要压缩的图片集合
private CompressImage.CompressListener listener; // 压缩监听,告知MainActivity
private CompressConfig config; // 压缩配置
/**
* 私有实现
*
* @param context 上下文
* @param config 配置
* @param images 图片集合
* @param listener 监听
* @return
*/
private CompressImageManager(Context context, CompressConfig config,
ArrayList<Photo> images, CompressListener listener) {
compressImageUtil = new CompressImageUtil(context, config);
this.config = config;
this.images = images;
this.listener = listener;
}
/**
* 静态方法,new实现
*
* @param context 上下文
* @param config 配置
* @param images 图片集合
* @param listener 监听
* @return
*/
public static CompressImage build(Context context, CompressConfig config,
ArrayList<Photo> images, CompressImage.CompressListener listener) {
return new CompressImageManager(context, config, images, listener);
}
@Override
public void compress() {
if (images == null || images.isEmpty()) {
listener.onCompressFailed(images, "集合为空");
return;
}
for (Photo image : images) {
if (image == null) {
listener.onCompressFailed(images, "某图片为空");
return;
}
}
// 开始递归压缩,从第一张开始
compress(images.get(0));
}
// 从第一张开始,index = 0
private void compress(Photo image) {
// 路径为空
if (TextUtils.isEmpty(image.getOriginalPath())) {
// 继续
continueCompress(image, false);
return;
}
// 文件不存在
File file = new File(image.getOriginalPath());
if (!file.exists() || !file.isFile()) {
continueCompress(image, false);
return;
}
// < 200KB
if (file.length() < config.getMaxSize()) {
continueCompress(image, true);
return;
}
// 单张压缩
compressImageUtil.compress(image.getOriginalPath(), new CompressResultListener() {
@Override
public void onCompressSuccess(String imgPath) {
image.setCompressPath(imgPath);
continueCompress(image, true);
}
@Override
public void onCompressFailed(String imgPath, String error) {
continueCompress(image, false, error);
}
});
}
private void continueCompress(Photo image, boolean bool, String... error) {
image.setCompressed(bool);
// 当前图片的索引
int index = images.indexOf(image);
if (index == images.size() - 1) { // 最后一张
handlerCallback(error);
} else {
compress(images.get(index + 1));
}
}
private void handlerCallback(String... error) {
if (error.length > 0) {
listener.onCompressFailed(images, error[0]);
return;
}
for (Photo image : images) {
// 如果存在没有压缩的图片,或者压缩失败的
if (!image.isCompressed()) {
listener.onCompressFailed(images, image.getOriginalPath() + "压缩失败");
return;
}
}
listener.onCompressSuccess(images);
}
}
根据传人图片路径,以及压缩方式进行对应压缩回调:
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.os.Handler;
import android.text.TextUtils;
import android.util.Log;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import com.netease.image.library.config.CompressConfig;
import com.netease.image.library.listener.CompressResultListener;
import com.netease.image.library.utils.Constants;
/**
* 压缩照片
*/
public class CompressImageUtil {
private CompressConfig config;
private Context context;
private Handler mhHandler = new Handler();
public CompressImageUtil(Context context, CompressConfig config) {
this.context = context;
this.config = config == null ? CompressConfig.getDefaultConfig() : config;
}
public void compress(String imgPath, CompressResultListener listener) {
if (config.isEnablePixelCompress()) {
try {
compressImageByPixel(imgPath, listener);
} catch (FileNotFoundException e) {
listener.onCompressFailed(imgPath, String.format("图片压缩失败,%s", e.toString()));
e.printStackTrace();
}
} else {
compressImageByQuality(BitmapFactory.decodeFile(imgPath), imgPath, listener);
}
}
/**
* 多线程压缩图片的质量
*/
private void compressImageByQuality(final Bitmap bitmap, final String imgPath, final CompressResultListener listener) {
if (bitmap == null) {
sendMsg(false, imgPath, "像素压缩失败,bitmap为空", listener);
return;
}
//开启多线程进行压缩处理
new Thread(() -> {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int options = 100;
bitmap.compress(Bitmap.CompressFormat.JPEG, options, baos); // 质量压缩方法,把压缩后的数据存放到baos中 (100表示不压缩,0表示压缩到最小)
while (baos.toByteArray().length > config.getMaxSize()) { // 循环判断如果压缩后图片是否大于指定大小,大于继续压缩
baos.reset(); // 重置baos即让下一次的写入覆盖之前的内容
options -= 5; // 图片质量每次减少5
if (options <= 5) options = 5; // 如果图片质量小于5,为保证压缩后的图片质量,图片最底压缩质量为5
bitmap.compress(Bitmap.CompressFormat.JPEG, options, baos); // 将压缩后的图片保存到baos中
if (options == 5) break; // 如果图片的质量已降到最低则,不再进行压缩
}
try {
File thumbnailFile = getThumbnailFile(new File(imgPath));
FileOutputStream fos = new FileOutputStream(thumbnailFile);//将压缩后的图片保存的本地上指定路径中
fos.write(baos.toByteArray());
fos.flush();
fos.close();
baos.flush();
baos.close();
bitmap.recycle();
sendMsg(true, thumbnailFile.getPath(), null, listener);
} catch (Exception e) {
sendMsg(false, imgPath, "质量压缩失败", listener);
e.printStackTrace();
}
}).start();
}
/**
* 按比例缩小图片的像素以达到压缩的目的
*/
private void compressImageByPixel(String imgPath, CompressResultListener listener) throws FileNotFoundException {
if (imgPath == null) {
sendMsg(false, null, "要压缩的文件不存在", listener);
return;
}
BitmapFactory.Options newOpts = new BitmapFactory.Options();
newOpts.inJustDecodeBounds = true; // 只读边,不读内容
BitmapFactory.decodeFile(imgPath, newOpts);
newOpts.inJustDecodeBounds = false;
int width = newOpts.outWidth;
int height = newOpts.outHeight;
float maxSize = config.getMaxPixel();
int be = 1;
if (width >= height && width > maxSize) { // 缩放比,用高或者宽其中较大的一个数据进行计算
be = (int) (newOpts.outWidth / maxSize);
be++;
} else if (width < height && height > maxSize) {
be = (int) (newOpts.outHeight / maxSize);
be++;
}
if (width <= config.getUnCompressNormalPixel() || height <= config.getUnCompressNormalPixel()) {
be = 2;
if (width <= config.getUnCompressMinPixel() || height <= config.getUnCompressMinPixel()) be = 1;
}
newOpts.inSampleSize = be; // 设置采样率
newOpts.inPreferredConfig = Config.ARGB_8888; // 该模式是默认的,可不设
newOpts.inPurgeable = true; // 同时设置才会有效
newOpts.inInputShareable = true; // 当系统内存不够时候图片自动被回收
Bitmap bitmap = BitmapFactory.decodeFile(imgPath, newOpts);
if (config.isEnableQualityCompress()) {
compressImageByQuality(bitmap, imgPath, listener); // 压缩好比例大小后再进行质量压缩
} else {
File thumbnailFile = getThumbnailFile(new File(imgPath));
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, new FileOutputStream(thumbnailFile));
listener.onCompressSuccess(thumbnailFile.getPath());
}
}
private File getThumbnailFile(File file) {
if (file == null || !file.exists()) return file;
return getPhotoCacheDir(file);
}
private File getPhotoCacheDir(File file) {
if (TextUtils.isEmpty(config.getCacheDir())) config.setCacheDir(Constants.COMPRESS_CACHE);
File mCacheDir = new File(Constants.BASE_CACHE_PATH
+ context.getPackageName() + "/cache", config.getCacheDir());
Log.e("netease >>> ", mCacheDir.getAbsolutePath());
if (!mCacheDir.mkdirs() && (!mCacheDir.exists() || !mCacheDir.isDirectory())) {
return file;
} else {
return new File(mCacheDir, "compress_" + file.getName());
}
}
/**
* 发送压缩结果的消息
*
* @param isSuccess 压缩是否成功
*/
private void sendMsg(final boolean isSuccess, final String imagePath, final String message, final CompressResultListener listener) {
mhHandler.post(() -> {
if (isSuccess) {
listener.onCompressSuccess(imagePath);
} else {
listener.onCompressFailed(imagePath, message);
}
});
}
}
最终调用方式:
import android.Manifest;
import android.app.ProgressDialog;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import com.netease.image.compress.utils.UriParseUtils;
import com.netease.image.library.CompressImageManager;
import java.io.File;
import java.util.ArrayList;
import com.netease.image.library.bean.Photo;
import com.netease.image.library.config.CompressConfig;
import com.netease.image.library.listener.CompressImage;
import com.netease.image.library.utils.CachePathUtils;
import com.netease.image.library.utils.CommonUtils;
import com.netease.image.library.utils.Constants;
public class MainActivity extends AppCompatActivity implements CompressImage.CompressListener {
private CompressConfig compressConfig; // 压缩配置
private ProgressDialog dialog; // 压缩加载框
private String cameraCachePath; // 拍照源文件路径
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initPermission();
compressConfig = CompressConfig.builder()
.setUnCompressMinPixel(1000) // 最小像素不压缩,默认值:1000
.setUnCompressNormalPixel(2000) // 标准像素不压缩,默认值:2000
.setMaxPixel(1000) // 长或宽不超过的最大像素 (单位px),默认值:1200
.setMaxSize(100 * 1024) // 压缩到的最大大小 (单位B),默认值:200 * 1024 = 200KB
.enablePixelCompress(true) // 是否启用像素压缩,默认值:true
.enableQualityCompress(true) // 是否启用质量压缩,默认值:true
.enableReserveRaw(true) // 是否保留源文件,默认值:true
.setCacheDir("") // 压缩后缓存图片路径,默认值:Constants.COMPRESS_CACHE
.setShowCompressDialog(true) // 是否显示压缩进度条,默认值:false
.create();
compressMore();
}
private void compressMore() {
// 测试多张图片同时压缩
ArrayList<Photo> photos = new ArrayList<>();
photos.add(new Photo("/storage/emulated/0/DCIM/Camera/IMG_20171108_151541.jpg"));
photos.add(new Photo("/storage/emulated/0/DCIM/Camera/IMG_20171011_095724.jpg"));
photos.add(new Photo("/storage/emulated/0/DCIM/Camera/IMG_20171011_092207.jpg"));
photos.add(new Photo("/storage/emulated/0/DCIM/Camera/IMG_20170608_113509.jpg"));
photos.add(new Photo("/storage/emulated/0/tencent/MicroMsg/WeiXin/mmexport1535449679877.jpg"));
photos.add(new Photo("/storage/emulated/0/autoLite/cameraImg/1535016551150.jpg"));
photos.add(new Photo("/storage/emulated/0/Download/微信图片_20171205095927.jpg"));
photos.add(new Photo("/storage/emulated/0/Pictures/camera_20181115_111332.jpg"));
photos.add(new Photo("/storage/emulated/0/Pictures/camera_20180706_173207.jpg"));
compress(photos);
}
// 点击拍照
public void camera(View view) {
// FileProvider
Uri outputUri;
File file = CachePathUtils.getCameraCacheFile();
;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
outputUri = UriParseUtils.getCameraOutPutUri(this, file);
} else {
outputUri = Uri.fromFile(file);
}
cameraCachePath = file.getAbsolutePath();
// 启动拍照
CommonUtils.hasCamera(this, CommonUtils.getCameraIntent(outputUri), Constants.CAMERA_CODE);
}
// 点击相册
public void album(View view) {
CommonUtils.openAlbum(this, Constants.ALBUM_CODE);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
// 拍照返回
if (requestCode == Constants.CAMERA_CODE && resultCode == RESULT_OK) {
// 压缩(集合?单张)
preCompress(cameraCachePath);
}
// 相册返回
if (requestCode == Constants.ALBUM_CODE && resultCode == RESULT_OK) {
if (data != null) {
Uri uri = data.getData();
String path = UriParseUtils.getPath(this, uri);
// 压缩(集合?单张)
preCompress(path);
}
}
}
// 准备压缩,封装图片集合
private void preCompress(String photoPath) {
ArrayList<Photo> photos = new ArrayList<>();
photos.add(new Photo(photoPath));
if (!photos.isEmpty()) compress(photos);
}
// 开始压缩
private void compress(ArrayList<Photo> photos) {
if (compressConfig.isShowCompressDialog()) {
Log.e("netease >>> ", "开启了加载框");
dialog = CommonUtils.showProgressDialog(this, "压缩中……");
}
CompressImageManager.build(this, compressConfig, photos, this).compress();
}
@Override
public void onCompressSuccess(ArrayList<Photo> arrayList) {
Log.e("netease >>> ", "压缩成功");
if (dialog != null && !isFinishing()) {
dialog.dismiss();
}
}
@Override
public void onCompressFailed(ArrayList<Photo> arrayList, String error) {
Log.e("netease >>> ", error);
if (dialog != null && !isFinishing()) {
dialog.dismiss();
}
}
private void initPermission() {
// 运行时权限申请
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
String[] perms = {Manifest.permission.CAMERA,
Manifest.permission.WRITE_EXTERNAL_STORAGE};
if (checkSelfPermission(perms[0]) == PackageManager.PERMISSION_DENIED ||
checkSelfPermission(perms[1]) == PackageManager.PERMISSION_DENIED) {
requestPermissions(perms, 200);
}
}
}
}