作为android开发的新手,前阵子做了个关于图片处理和剪裁的demo;参考了网上的一些 资料,结合了自身的一些理解,于是就过来发表下新的,顺便也给这个知识点做下总结,让很多新手可以少走些弯路,当然文章中可能也有些不足,也希望大家指出,共同进步^ ^!
图片的获得一般就是从相册中获取和拍照,我们先来说说从相册中获取。最基本的调用系统图库:
Intent intent = new Intent(Intent.ACTION_PICK,MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(intent, REQUEST_CODE_IMAGE);
但是经过测试会发现加载的图片如果过大就会出现OOM(不知道的小伙伴请自行百度^^),所以就要把图片临时储存在文件夹中在调用显示就可以了,拍照取得的图片也是一样,为了防止OOM也要用相同的处理方法:
Intent Intent = new Intent(Intent.ACTION_PICK, new Intent(Intent.ACTION_PICK, null);
Intent.setType("image/*");//从所有图片中进行选择
Intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());//把图片转成JPEG形式保存
Intent.putExtra(MediaStore.EXTRA_OUTPUT, getTempUri());private Uri getTempUri() {
return Uri.fromFile(getTempFile());
}
private File getTempFile() {
if (Environment.getExternalStorageState().equals(
Environment.MEDIA_MOUNTED)) {
File file = new File(Environment.getExternalStorageDirectory(),
Constants.TEMP_PHOTO_FILE);
try {
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
return file;
} else {
return null;
}
}
拍照时:
private Uri getTempUri() { return Uri.fromFile(getTempFile()); } private File getTempFile() { if (Environment.getExternalStorageState().equals( Environment.MEDIA_MOUNTED)) { File file = new File(Environment.getExternalStorageDirectory(), Constants.TEMP_PHOTO_FILE); try { file.createNewFile(); } catch (IOException e) { e.printStackTrace(); } return file; } else { return null; } }
try {
getGoodsImageMethodChooser.dismiss();
Intent intentFromCapture = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intentFromCapture.putExtra(Constants.OUTPUT_FORMAT, Bitmap.CompressFormat.JPEG.toString());
intentFromCapture.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 0);
File path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM);
File tempFile = new File(path, Constants.TEMP_PHOTO_FILE);
// 判断存储卡是否可以用,可用进行存储
intentFromCapture.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(tempFile));
startActivityForResult(intentFromCapture, CAMERA_REQUEST_CODE);
} catch (Exception e) {
}
返回时:
/**
* 返回
*/
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode != RESULT_CANCELED && requestCode == IMAGE_REQUEST_CODE) {
handleImage(data.getData());// 手机相册返回
}
if (resultCode != RESULT_CANCELED && requestCode == CAMERA_REQUEST_CODE) {
File path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM);
File tempFile2 = new File(path, Constants.TEMP_PHOTO_FILE);
Bitmap bitmap =decodeUriAsBitmap(Uri.fromFile(tempFile2));
handleImage(bitmap);// 拍照返回
}
}
需要注意的是在把图片放到ImageView中的时候要用setImageBitmap()这个方法,而不要用setImageURL的方法,因为效率不一样而且在加载某些大图片时setImageURL方法在某些机型可能有问题。
再来说说图片剪裁,其实是差不多的,就是多了一个剪裁的步凑而已:
/**
* 裁剪图片方法实现
*
* @param uri
*/
public void startPhotoZoomCertificate(Uri uri) {
/*
* 至于下面这个Intent的ACTION是怎么知道的,大家可以看下自己路径下的如下网页
* yourself_sdk_path/docs/reference/android/content/Intent.html
*/
try {
Intent intent = new Intent("com.android.camera.action.CROP");
intent.setDataAndType(uri, "image/*");
// 下面这个crop=true是设置在开启的Intent中设置显示的VIEW可裁剪
intent.putExtra("crop", "true");
// aspectX aspectY 是宽高的比例
intent.putExtra("aspectX", 16);
intent.putExtra("aspectY", 9);
// outputX outputY 是裁剪图片宽高
intent.putExtra("outputX", 800);
intent.putExtra("outputY", 450);
intent.putExtra("outputFormat",
Bitmap.CompressFormat.JPEG.toString());
intent.putExtra("noFaceDetection", true);
intent.putExtra(MediaStore.EXTRA_OUTPUT, uritempFile);
intent.putExtra("return-data", false);// 设置为不返回数据
startActivityForResult(intent, 3);
} catch (Exception e) {
}
} //uritempFile是剪裁保存的路径 可以自己定义,我把它定义成这样private Uri uritempFile = Uri.parse("file://" + "/"
+ Environment.getExternalStorageDirectory().getPath() + "/"
+ "small.jpg");
在返回时写成这样:
//uritempFile是剪裁保存的路径 可以自己定义,我把它定义成这样private Uri uritempFile = Uri.parse("file://" + "/" + Environment.getExternalStorageDirectory().getPath() + "/" + "small.jpg");
/**
* 返回
*/
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode != RESULT_CANCELED && requestCode == IMAGE_REQUEST_CODE) {
startPhotoZoomCertificate(data.getData());// 手机相册返回
}
if (resultCode != RESULT_CANCELED && requestCode == CAMERA_REQUEST_CODE) {
File path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM);
File tempFile2 = new File(path, Constants.TEMP_PHOTO_FILE);
Bitmap bitmap =decodeUriAsBitmap(Uri.fromFile(tempFile2));
startPhotoZoomCertificate(Uri.fromFile(tempFile2));// 拍照返回
} if (requestCode == 3&& resultCode==RESULT_OK) { //&& data != null
Bitmap bitmap = null;
try {
// BitmapFactory.Options options = new BitmapFactory.Options();
// options.inSampleSize = 2;//BitmapFactory.decodeStream压缩图片的方法
// bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(uritempFile),null,options);
bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(uritempFile));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
if (bitmap != null) {
handleImage(bitmap);
}
}
}
public void handleImage(Bitmap photo) {
goodsImage = photo;// decode bitmap
goodsImageButton.setImageBitmap(photo); //goodsImageButton就是我们定义的ImageView了
}
图片的选择和剪裁大概就是这样了,本人比较懒,所以原理什么的都没详说,大家不懂的自己百度下吧^ ^。其实这样写完一般情况下是没问题的,但是android现在碎片化这么严重,有些记机子的剪裁会有问题,如果你装过QQ游览器等软件,在从系统相册选取图片时,可能也会出现拿不到图片的情况!什么?那呢?老子裤子都脱了,看完文章,你竟然说有问题!!!
不要慌,其实对于android的图片选择和剪裁,其实还是用第三方架包比较靠谱,在GitHub上有很多优秀的架包可以用(当然你牛逼到自己可以写当我没说);这里就好人做到底把我辛辛苦苦找的架包和大家分享下吧![大笑](http://static.blog.csdn.net/xheditor/xheditor_emot/default/laugh.gif)
if (requestCode == 3&& resultCode==RESULT_OK) { //&& data != null Bitmap bitmap = null; try { // BitmapFactory.Options options = new BitmapFactory.Options(); // options.inSampleSize = 2;//BitmapFactory.decodeStream压缩图片的方法 // bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(uritempFile),null,options); bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(uritempFile)); } catch (FileNotFoundException e) { e.printStackTrace(); } if (bitmap != null) { handleImage(bitmap); } } }
public void handleImage(Bitmap photo) { goodsImage = photo;// decode bitmap goodsImageButton.setImageBitmap(photo); //goodsImageButton就是我们定义的ImageView了}
图片剪裁
uCrop
:项目地址 https://github.com/Yalantis/uCrop 项目目标是提供终极的,灵活的图片剪裁,但是个人认为功能太多了,太耗内存,低端机跑起来会很卡,而且有些功能对于只需要剪裁功能的根本没必要。
android-crop:项目地址https://github.com/jdamcd/android-crop 没有uCrop这么多功能 简简单单,就是剪裁的功能(本人就是用这个架包的)。
图片选择
MultilmageSelector:
项目地址https://github.com/lovetuzitong/MultiImageSelector 是个高仿微信朋友圈的图片选择的工具库,大家可以试试。
最后谢谢大家,有问题可以留言,大家一起进步^ ^..