在Activity中加入以下代码段:
private final int CODE_CROP = 0x131;//用于请求系统剪裁的请求码
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what){
case ImageCropUtil.Hand_Compress_Ok://图片压缩完成
modify_type = MODIFY_USER_HEAD_IMAGE;
File file = new File(ImageCropUtil.getHeadCompressPath());//图片地址在ImageCropUtil中定义好的固定值
mFiles.put(file.getName(), file);
presenter.modifyUserHeadImage(mFiles);
break;
case ImageCropUtil.Hand_Compress_Failure://图片压缩失败
File file1 = new File(ImageCropUtil.ouputFilePath);//用压缩之前的图片
mFiles.put(file1.getName(), file1);
presenter.modifyUserHeadImage(mFiles);
break;
}
}
};
//跳转裁剪图片
ImageCropUtil.cropPhoto(this, headPath, CODE_CROP);
二、剪裁完成后调用压缩图片方法:【activity中的onActivityResult方法中调用】(可以不调用,如果不调用你就发送到服务端很可能报错:accep 427 byte but received 8192)
if (requestCode == CODE_CROP && resultCode == RESULT_OK) {
ImageCropUtil.compress15k(this, ImageCropUtil.ouputFilePath, handler);
}
三、剪裁完成后会返回到handler中四、以下是ImageCropUtil类:
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.media.ExifInterface;
import android.net.Uri;
import android.os.Environment;
import android.os.Handler;
import android.provider.MediaStore;
import android.util.DisplayMetrics;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* CreateTime 2017/9/18 16:10
* Author LiuShiHua
* Description:
*/
public class ImageCropUtil {
public static final int Hand_Compress_Ok = 0x66;//图片压缩成功
public static final int Hand_Compress_Failure = 0x44;//图片压缩失败
//压缩后的图片文件地址
public static String getHeadCompressPath() {
return Environment.getExternalStorageDirectory() + "/ettda/temp/head_compress_output.jpg";
}
//剪裁后的文件地址
public static final String ouputFilePath = Environment.getExternalStorageDirectory() + "/ettda/temp/head_output.jpg";
/**
* 裁剪原始的图片(系统自带的剪裁工具)
*
* @param activity 上下文
* @param filePath 图片源路径
* @param CODE_REQUEST_CROP 请求剪裁的请求码
*/
public static void cropPhoto(Activity activity, String filePath, int CODE_REQUEST_CROP) {
File file = new File(filePath);
if (!file.exists()) return;
File tempFile = new File(ouputFilePath);
if (!tempFile.exists()) {
File parent = tempFile.getParentFile();
parent.mkdirs();
try {
tempFile.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
Uri uri = Uri.fromFile(tempFile);
Intent intent = new Intent("com.android.camera.action.CROP");
intent.setDataAndType(uri, "image/*");
intent.putExtra("crop", "true");// 设置裁剪
intent.putExtra("aspectX", 1); // aspectX , aspectY :宽高的比例
intent.putExtra("aspectY", 1);
intent.putExtra("outputX", 650);// outputX , outputY : 裁剪图片宽高
intent.putExtra("outputY", 650);
//剪裁后过小时,拉伸
intent.putExtra("scale", true);
intent.putExtra("scaleUpIfNeeded", true);
/**
* 此方法返回的图片只能是小图片(sumsang测试为高宽160px的图片)
* 故将图片保存在Uri中,调用时将Uri转换为Bitmap,此方法还可解决miui系统不能return data的问题
*/
Uri uritempFile = Uri.parse("file://" + "/" + ouputFilePath);//格式别搞错了
intent.putExtra(MediaStore.EXTRA_OUTPUT, uritempFile);//输出图片文件
//是否返回bitmap对象
intent.putExtra("return-data", false);
intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
activity.startActivityForResult(intent, CODE_REQUEST_CROP);
}
/**
* 压缩图片文件(1.5M以下)
*
* @param context
* @param srcPath
* @return
*/
public static void compress15k(final Activity context, final String srcPath, final Handler handler) {
if (srcPath == null) {
handler.sendEmptyMessage(Hand_Compress_Failure);
return;
}
File file = new File(srcPath);
if (!file.exists()){
handler.sendEmptyMessage(Hand_Compress_Failure);
return;
}
new Thread() {
@Override
public void run() {
super.run();
String pathNew = getHeadCompressPath();
File tempFile = new File(pathNew);
if (!tempFile.exists()) {
File parent = tempFile.getParentFile();
parent.mkdirs();
try {
tempFile.createNewFile();
} catch (IOException e) {
e.printStackTrace();
handler.sendEmptyMessage(Hand_Compress_Failure);
return;
}
}
String fileName = tempFile.getAbsolutePath();
DisplayMetrics dm = new DisplayMetrics();
context.getWindowManager().getDefaultDisplay().getMetrics(dm);
float hh = dm.heightPixels;
float ww = dm.widthPixels;
BitmapFactory.Options opts = new BitmapFactory.Options();
opts.inJustDecodeBounds = false;
int w = opts.outWidth;
int h = opts.outHeight;
int size = 0;
if (w <= ww && h <= hh) {
size = 1;
} else {
double scale = w >= h ? w / ww : h / hh;
double log = Math.log(scale) / Math.log(2);
double logCeil = Math.ceil(log);
size = (int) Math.pow(2, logCeil);
}
opts.inSampleSize = size;
Bitmap bitmap = BitmapFactory.decodeFile(srcPath, opts);
Matrix m = new Matrix();
m.postRotate(digreeBitmap(srcPath));
bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), m, true);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int quality = 100;
bitmap.compress(Bitmap.CompressFormat.JPEG, quality, baos);
while (baos.toByteArray().length > 1536 * 1024) {//1.5M以下
baos.reset();
bitmap.compress(Bitmap.CompressFormat.JPEG, quality, baos);
quality -= 5;
}
try {
baos.writeTo(new FileOutputStream(fileName));
} catch (Exception e) {
e.printStackTrace();
handler.sendEmptyMessage(Hand_Compress_Failure);
return;
} finally {
try {
baos.flush();
baos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
handler.sendEmptyMessage(Hand_Compress_Ok);
}
}.start();
}
private static int digreeBitmap(String imgpath) {
int digree = 0;
ExifInterface exif = null;
try {
exif = new ExifInterface(imgpath);
} catch (IOException e) {
e.printStackTrace();
exif = null;
}
if (exif != null) {
// 读取图片中相机方向信息
int ori = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_UNDEFINED);
// 计算旋转角度
switch (ori) {
case ExifInterface.ORIENTATION_ROTATE_90:
digree = 90;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
digree = 180;
break;
case ExifInterface.ORIENTATION_ROTATE_270:
digree = 270;
break;
default:
digree = 0;
break;
}
}
return digree;
}
}