单纯的compile luban 还要默认添加rxjava 如果项目里 没有用到rxjava 所以也就不用继续添加他的代码
- 自己改编 主要修改launch方法 之前全部用rxjava 写的 现在写的AsyncTask
package org.xiaozhi.framework.util.luban;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.Matrix;
import android.media.ExifInterface;
import android.os.AsyncTask;
import android.text.TextUtils;
import android.util.Log;
import android.widget.Toast;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import cn.bingoogolapple.qrcode.core.BGAQRCodeUtil;
import cn.bingoogolapple.qrcode.zxing.QRCodeEncoder;
import static org.xiaozhi.framework.util.luban.Preconditions.checkNotNull;
public class Luban {
public static int FIRST_GEAR = 1;
public static int THIRD_GEAR = 3;
private static final String TAG = "Luban";
private static volatile Luban INSTANCE;
private final File mCacheDir;
private OnCompressListener compressListener;
private File mFile;
private String filename;
private Luban(File cacheDir) {
mCacheDir = cacheDir;
}
/**
* Returns a directory with a default name in the private cache directory of the application to use to store
* retrieved media and thumbnails.
*
* @param context A context.
*/
private static synchronized File getPhotoCacheDir(Context context) {
File cacheDir = context.getCacheDir();
if (cacheDir != null) {
String DEFAULT_DISK_CACHE_DIR = "luban_disk_cache";
File result = new File(cacheDir, DEFAULT_DISK_CACHE_DIR);
if (!result.mkdirs() && (!result.exists() || !result.isDirectory())) {
// File wasn't able to create a directory, or the result exists but not a directory
return null;
}
File noMedia = new File(cacheDir + "/.nomedia");
if (!noMedia.mkdirs() && (!noMedia.exists() || !noMedia.isDirectory())) {
return null;
}
return result;
}
if (Log.isLoggable(TAG, Log.ERROR)) {
Log.e(TAG, "default disk cache dir is null");
}
return null;
}
public static Luban get(Context context) {
if (INSTANCE == null) {
INSTANCE = new Luban(Luban.getPhotoCacheDir(context));
}
return INSTANCE;
}
public Luban launch() {
checkNotNull(mFile, "the image file cannot be null, please call .load() before this method!");
if (compressListener != null) compressListener.onStart();
if (mFile == null || !mFile.exists()) {
if (compressListener != null) {
compressListener.onError(new FileNotFoundException("inputFile not exists"));
}
return this;
}
if (!mFile.canRead()) {
if (compressListener != null) {
compressListener.onError(new IOException("inputFile is cannot read"));
}
return this;
}
new AsyncTask<Void, Void, File>() {
@Override
protected File doInBackground(Void... params) {
return Compress(mFile);
}
@Override
protected void onPostExecute(File file) {
if (file != null) {
if (compressListener != null) compressListener.onSuccess(file);
} else {
if (compressListener != null) compressListener.onError(new Exception("压缩失败"));
}
}
}.execute();
return this;
}
public Luban load(File file) {
mFile = file;
return this;
}
public Luban setCompressListener(OnCompressListener listener) {
compressListener = listener;
return this;
}
/**
* @deprecated
*/
public Luban putGear(int gear) {
return this;
}
/**
* @deprecated
*/
public Luban setFilename(String filename) {
this.filename = filename;
return this;
}
private File Compress(File file) {
String thumb = mCacheDir.getAbsolutePath() + File.separator +
(TextUtils.isEmpty(filename) ? System.currentTimeMillis() : filename) + ".jpg";
double size;
String filePath = file.getAbsolutePath();
int angle = getImageSpinAngle(filePath);
int width = getImageSize(filePath)[0];
int height = getImageSize(filePath)[1];
int thumbW = width % 2 == 1 ? width + 1 : width;
int thumbH = height % 2 == 1 ? height + 1 : height;
width = thumbW > thumbH ? thumbH : thumbW;
height = thumbW > thumbH ? thumbW : thumbH;
double scale = ((double) width / height);
if (scale <= 1 && scale > 0.5625) {
if (height < 1664) {
if (file.length() / 1024 < 150) return file;
size = (width * height) / Math.pow(1664, 2) * 150;
size = size < 60 ? 60 : size;
} else if (height >= 1664 && height < 4990) {
thumbW = width / 2;
thumbH = height / 2;
size = (thumbW * thumbH) / Math.pow(2495, 2) * 300;
size = size < 60 ? 60 : size;
} else if (height >= 4990 && height < 10240) {
thumbW = width / 4;
thumbH = height / 4;
size = (thumbW * thumbH) / Math.pow(2560, 2) * 300;
size = size < 100 ? 100 : size;
} else {
int multiple = height / 1280 == 0 ? 1 : height / 1280;
thumbW = width / multiple;
thumbH = height / multiple;
size = (thumbW * thumbH) / Math.pow(2560, 2) * 300;
size = size < 100 ? 100 : size;
}
} else if (scale <= 0.5625 && scale > 0.5) {
if (height < 1280 && file.length() / 1024 < 200) return file;
int multiple = height / 1280 == 0 ? 1 : height / 1280;
thumbW = width / multiple;
thumbH = height / multiple;
size = (thumbW * thumbH) / (1440.0 * 2560.0) * 400;
size = size < 100 ? 100 : size;
} else {
int multiple = (int) Math.ceil(height / (1280.0 / scale));
thumbW = width / multiple;
thumbH = height / multiple;
size = ((thumbW * thumbH) / (1280.0 * (1280 / scale))) * 500;
size = size < 100 ? 100 : size;
}
return compress(filePath, thumb, thumbW, thumbH, angle, (long) size);
}
/**
* obtain the image's width and height
*
* @param imagePath the path of image
*/
public int[] getImageSize(String imagePath) {
int[] res = new int[2];
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
options.inSampleSize = 1;
BitmapFactory.decodeFile(imagePath, options);
res[0] = options.outWidth;
res[1] = options.outHeight;
return res;
}
/**
* obtain the thumbnail that specify the size
*
* @param imagePath the target image path
* @param width the width of thumbnail
* @param height the height of thumbnail
* @return {@link Bitmap}
*/
private Bitmap compress(String imagePath, int width, int height) {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(imagePath, options);
int outH = options.outHeight;
int outW = options.outWidth;
int inSampleSize = 1;
if (outH > height || outW > width) {
int halfH = outH / 2;
int halfW = outW / 2;
while ((halfH / inSampleSize) > height && (halfW / inSampleSize) > width) {
inSampleSize *= 2;
}
}
options.inSampleSize = inSampleSize;
options.inJustDecodeBounds = false;
int heightRatio = (int) Math.ceil(options.outHeight / (float) height);
int widthRatio = (int) Math.ceil(options.outWidth / (float) width);
if (heightRatio > 1 || widthRatio > 1) {
if (heightRatio > widthRatio) {
options.inSampleSize = heightRatio;
} else {
options.inSampleSize = widthRatio;
}
}
options.inJustDecodeBounds = false;
return BitmapFactory.decodeFile(imagePath, options);
}
/**
* obtain the image rotation angle
*
* @param path path of target image
*/
private int getImageSpinAngle(String path) {
int degree = 0;
try {
ExifInterface exifInterface = new ExifInterface(path);
int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
switch (orientation) {
case ExifInterface.ORIENTATION_ROTATE_90:
degree = 90;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
degree = 180;
break;
case ExifInterface.ORIENTATION_ROTATE_270:
degree = 270;
break;
}
} catch (IOException e) {
e.printStackTrace();
}
return degree;
}
/**
* 指定参数压缩图片
* create the thumbnail with the true rotate angle
*
* @param largeImagePath the big image path
* @param thumbFilePath the thumbnail path
* @param width width of thumbnail
* @param height height of thumbnail
* @param angle rotation angle of thumbnail
* @param size the file size of image
*/
private File compress(String largeImagePath, String thumbFilePath, int width, int height, int angle, long size) {
Bitmap thbBitmap = compress(largeImagePath, width, height);
thbBitmap = rotatingImage(angle, thbBitmap);
return saveImage(thumbFilePath, thbBitmap, size);
}
/**
* 旋转图片
* rotate the image with specified angle
*
* @param angle the angle will be rotating 旋转的角度
* @param bitmap target image 目标图片
*/
private static Bitmap rotatingImage(int angle, Bitmap bitmap) {
//rotate image
Matrix matrix = new Matrix();
matrix.postRotate(angle);
//create a new image
return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
}
/**
* 保存图片到指定路径
* Save image with specified size
*
* @param filePath the image file save path 储存路径
* @param bitmap the image what be save 目标图片
* @param size the file size of image 期望大小
*/
private File saveImage(String filePath, Bitmap bitmap, long size) {
checkNotNull(bitmap, TAG + "bitmap cannot be null");
File result = new File(filePath.substring(0, filePath.lastIndexOf("/")));
if (!result.exists() && !result.mkdirs()) return null;
ByteArrayOutputStream stream = new ByteArrayOutputStream();
int options = 100;
bitmap.compress(Bitmap.CompressFormat.JPEG, options, stream);
while (stream.toByteArray().length / 1024 > size && options > 6) {
stream.reset();
options -= 6;
bitmap.compress(Bitmap.CompressFormat.JPEG, options, stream);
}
bitmap.recycle();
try {
FileOutputStream fos = new FileOutputStream(filePath);
fos.write(stream.toByteArray());
fos.flush();
fos.close();
stream.close();
} catch (IOException e) {
e.printStackTrace();
}
return new File(filePath);
}
}
- 这是朋友修改的版本 还没来得及用
package com.bdyue.dialoguelibrary.util;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.media.ExifInterface;
import com.bdyue.common.util.DisplayUtil;
import com.bdyue.common.util.ThreadPoolAsyncTask;
import com.bdyue.dialoguelibrary.interfaces.DialogueCompressListener;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
/**
* 图片压缩<br/>
* Created by cds on 2016/9/5.
*/
public class ImageCompressUtil {
/**
* 参考第一级最大压缩大小
*/
private long firstMaxSize = 150;
/**
* 参考第二级最大压缩大小
*/
private long secondMaxSize = 200;
/**
* 参考的第一级最小压缩大小
*/
private long firstMinSize = 60;
/**
* 参考的第二级最小压缩大小
*/
private long secondMinSize = 120;
private Activity mActivity;
private File inputFile;
private File resultFile;
private DialogueCompressListener listener;
public ImageCompressUtil(Activity activity, File inputFile, File resultFile, DialogueCompressListener listener) {
mActivity = activity;
this.inputFile = inputFile;
this.resultFile = resultFile;
this.listener = listener;
}
public ImageCompressUtil(Activity context, File inputFile, File resultFile, DialogueCompressListener listener,
long firstMaxSize, long secondMaxSize, long firstMinSize, long secondMinSize) {
mActivity = context;
this.inputFile = inputFile;
this.resultFile = resultFile;
this.listener = listener;
this.firstMaxSize = firstMaxSize;
this.secondMaxSize = secondMaxSize;
this.firstMinSize = firstMinSize;
this.secondMinSize = secondMinSize;
}
/**
* 开始压缩
*/
public void start() {
if (mActivity == null || mActivity.isFinishing()) return;
if (listener != null) {
listener.onStart();
}
if (inputFile == null || !inputFile.exists()) {
if (listener != null) {
listener.onError(new FileNotFoundException("inputFile not exists"));
}
return;
}
if (!inputFile.canRead()) {
if (listener != null) {
listener.onError(new IOException("inputFile is cannot read"));
}
return;
}
if (resultFile == null) {
if (listener != null) {
listener.onError(new IllegalArgumentException("inputFile is null"));
}
return;
}
new CompressTask().executeThreadPool();
}
/**
* 转换图片
*/
private class CompressTask extends ThreadPoolAsyncTask<File,File,Boolean> {
@Override
protected Boolean doInBackground(File[] params) {
return compress();
}
@Override
protected void onPostExecute(Boolean result) {
if (mActivity == null || mActivity.isFinishing()) return;
if (result) {
if (listener != null) {
listener.onSuccess();
}
}
}
}
/**
* 进行转换
* @return true or false
*/
private boolean compress() {
boolean saveSuccess;
boolean shouldCompress;
try {
FileInputStream inputStream = new FileInputStream(inputFile);
FileOutputStream resultStream = new FileOutputStream(resultFile);
double size = firstMinSize;
int angle = getImageSpinAngle(inputFile.getAbsolutePath());
int[] wh = DisplayUtil.getImageWH(inputFile.getAbsolutePath());
int shortSide = wh[0];
int longSide = wh[1];
int resultShort = shortSide % 2 == 1 ? shortSide + 1 : shortSide;
int resultLong = longSide % 2 == 1 ? longSide + 1 : longSide;
if (inputFile.length() / 1024.0f < firstMinSize){
// 小于60Kb的图片不进行任何压缩
shouldCompress = false;
}else {
shortSide = resultShort > resultLong ? resultLong : resultShort;
longSide = resultShort > resultLong ? resultShort : resultLong;
// 长边和小边的比例
double scale = ((double) shortSide / longSide);
if (scale <= 1 && scale > 0.5625) {
// 图片处于 [1:1 ~ 9:16) 比例范围内
if (longSide < 1664) {
if (inputFile.length() / 1024.0f < firstMaxSize) {
shouldCompress = false;
} else {
size = (shortSide * longSide) / Math.pow(1664, 2) * firstMaxSize;
size = size < firstMinSize ? firstMinSize : size;
shouldCompress = true;
}
} else if (longSide >= 1664 && longSide < 4990) {
resultShort = shortSide / 2;
resultLong = longSide / 2;
size = (resultShort * resultLong) / Math.pow(2495, 2) * 300;
size = size < firstMinSize ? firstMinSize : size;
shouldCompress = true;
} else if (longSide >= 4990 && longSide < 10240) {
resultShort = shortSide / 4;
resultLong = longSide / 4;
size = (resultShort * resultLong) / Math.pow(2560, 2) * 300;
size = size < secondMinSize ? secondMinSize : size;
shouldCompress = true;
} else {
float multiple = longSide / 1280 == 0 ? 1 : longSide / 1280.0f;
resultShort = (int)(shortSide / multiple);
resultLong = (int)(longSide / multiple);
size = (resultShort * resultLong) / Math.pow(2560, 2) * 300;
size = size < secondMinSize ? secondMinSize : size;
shouldCompress = true;
}
} else if (scale <= 0.5625 && scale > 0.5) {
// 图片处于 [9:16 ~ 1:2) 比例范围内
if (longSide < 1280 && inputFile.length() / 1024.0f < secondMaxSize){
shouldCompress = false;
} else {
float multiple = longSide / 1280 == 0 ? 1 : longSide / 1280.0f;
resultShort = (int) (shortSide / multiple);
resultLong = (int) (longSide / multiple);
size = (resultShort * resultLong) / (1440.0 * 2560.0) * 400;
size = size < secondMinSize ? secondMinSize : size;
shouldCompress = true;
}
} else {
// 图片处于 [1:2 ~ 1:∞) 比例范围内 小边保持在400以上
if (scale < (400.0 / 1280.0)){
// 长边是小边的3倍以上时,进行稍微压缩
if (shortSide <= 400) {
// 小边小于400时不压缩
shouldCompress = false;
} else {
// 小边压缩到400
float multiple = shortSide / 400.0f;
resultShort = (int)(shortSide / multiple);
resultLong = (int)(longSide / multiple);
size = inputFile.length() / 1024.0 * multiple;
size = size < secondMinSize ? secondMinSize : size;
shouldCompress = true;
}
} else {
// 长短比在2到3时
float multiple = (float) (longSide / (1280.0 / scale));
resultShort = (int)(shortSide / multiple);
resultLong = (int)(longSide / multiple);
size = ((resultShort * resultLong) / (1280.0 * (1280 / scale))) * 500;
size = size < secondMinSize ? secondMinSize : size;
shouldCompress = true;
}
}
}
if (shouldCompress) {
// 图片转换
Bitmap resultBitmap = getBitmap(resultShort, resultLong);
resultBitmap = rotatingImage(angle, resultBitmap);
writeBitmap(resultBitmap, size, resultStream);
} else {
// 拷贝文件
copyFile(inputStream, resultStream);
}
inputStream.close();
resultStream.close();
resultStream.flush();
saveSuccess = true;
} catch (Exception ex) {
if (listener != null) {
listener.onError(ex);
}
saveSuccess = false;
}
return saveSuccess;
}
/**
* 获取bitmap
* @param resultShort resultShort
* @param resultLong resultLong
*/
private Bitmap getBitmap(int resultShort, int resultLong){
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(inputFile.getPath(), options);
int outShort, outLong;
if (options.outHeight > options.outWidth) {
outShort = options.outWidth;
outLong = options.outHeight;
} else {
outShort = options.outHeight;
outLong = options.outWidth;
}
int inSampleSize = 1;
int shortRatio = Math.round(outShort/ (float) resultShort);
int longRatio = Math.round(outLong / (float) resultLong);
Bitmap resultBitmap;
boolean shouldScale = false;
int shouldWidth = 0, shouldHeight = 0;
if (shortRatio > 1 && longRatio > 1) {
if (shortRatio > longRatio) {
if (shortRatio % 2 != 0) {
shortRatio = shortRatio / 2;
shouldScale = true;
if (options.outHeight > options.outWidth) {
shouldWidth = resultShort / shortRatio;
shouldHeight = resultLong / shortRatio;
} else {
shouldWidth = resultLong / shortRatio;
shouldHeight = resultShort / shortRatio;
}
}
inSampleSize = shortRatio;
} else {
if (longRatio % 2 != 0) {
longRatio = longRatio / 2;
shouldScale = true;
if (options.outHeight > options.outWidth) {
shouldWidth = resultShort / longRatio;
shouldHeight = resultLong / longRatio;
} else {
shouldWidth = resultLong / longRatio;
shouldHeight = resultShort / longRatio;
}
}
inSampleSize = longRatio;
}
}
options.inSampleSize = inSampleSize;
options.inJustDecodeBounds = false;
resultBitmap = BitmapFactory.decodeFile(inputFile.getPath(), options);
if (shouldScale) {
resultBitmap = Bitmap.createScaledBitmap(resultBitmap, shouldWidth, shouldHeight, false);
}
return resultBitmap;
}
/**
* 获取当前图片的旋转角度
* @param path 图片路径
*/
private int getImageSpinAngle(String path) {
int degree = 0;
try {
ExifInterface exifInterface = new ExifInterface(path);
int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
switch (orientation) {
case ExifInterface.ORIENTATION_ROTATE_90:
degree = 90;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
degree = 180;
break;
case ExifInterface.ORIENTATION_ROTATE_270:
degree = 270;
break;
}
} catch (IOException e) {
e.printStackTrace();
}
return degree;
}
/**
* 读入stream,保存图片
* @param bitmap bitmap
* @param size size
* @param stream stream
*/
private void writeBitmap(Bitmap bitmap, double size, FileOutputStream stream) throws IOException{
ByteArrayOutputStream byteArrayOs = new ByteArrayOutputStream();
DisplayUtil.compressBitmap(bitmap, size, byteArrayOs);
byteArrayOs.writeTo(stream);
byteArrayOs.close();
byteArrayOs.flush();
bitmap.recycle();
}
/**
* 旋转图片
* @param angle the angle will be rotating 旋转的角度
* @param bitmap target image 目标图片
*/
private static Bitmap rotatingImage(int angle, Bitmap bitmap) {
//rotate image
Matrix matrix = new Matrix();
matrix.postRotate(angle);
//create a new image
return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
}
/**
* 文件保存
* @param inputStream 输入流
* @param outputStream 输出流
* @throws IOException
*/
public static void copyFile(InputStream inputStream, OutputStream outputStream) throws IOException {
byte[] buffer = new byte[1024];
int byteRead;
while ((byteRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, byteRead);
}
}
}