在开发中,调用系统的相机拍照,或者图库选择图片是很常见的操作,有时候你会看到有的应用在选择图片的时候,会有个小方框,可以进行图片的裁剪选择,其实,这些都可以通过调用系统来实现。
1:调用系统的相机拍照。
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
}
在onActivityResult中,可以通过data来得到bitmap。
// Bundle extras = data.getExtras();
// Bitmap imageBitmap = (Bitmap) extras.get("data");
这个bitmap是个缩略图,意义不大,我们肯定希望能拿到拍照的原图。这个时候,需要传递一个File的实例,也就是照片保存的路径。
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
File photoFile = null;
try {
photoFile = createImageFile();
} catch (IOException ex) {
}
if (photoFile != null) {
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT,
Uri.fromFile(photoFile));
startActivityForResult(takePictureIntent, requestCode);
}
}
private File createImageFile() throws IOException {
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
File storageDir = Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES);
File image = File.createTempFile(
imageFileName, /* prefix */
".jpg", /* suffix */
storageDir /* directory */
);
mCurrentPhotoPath = image.getAbsolutePath();
Log.i(TAG,mCurrentPhotoPath);
return image;
}
其中,mCurrentPhotoPath就是拍照保存的路径,在onActivityResult中就可以获取图片,进行操作了。
2:调用系统的图库,选择图片。(在onActivityResult中通过URI来处理)
Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(intent, requestCode);
Uri photoUri = data.getData();
if (photoUri != null) {
String[] proj = { MediaStore.Images.Media.DATA };
Cursor actualimagecursor = managedQuery(photoUri, proj,
null, null, null);
try {
int index = actualimagecursor
.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
actualimagecursor.moveToFirst();
String img_path = actualimagecursor.getString(index);
mCurrentPhotoPath = img_path;
} catch (Exception e) {
e.printStackTrace();
}
}
3:调用系统的裁剪:
有的app在选择用户头像的时候,可以进行裁剪,其实系统本身就自带了,就是在拍照完或者选择完图库后,通过Intent了实现的。
public void zoomPhoto(){
Intent intent = new Intent("com.android.camera.action.CROP");
File f = new File(mCurrentPhotoPath);
Uri contentUri = Uri.fromFile(f);
intent.setDataAndType(contentUri, "image/*");
// crop为true是设置在开启的intent中设置显示的view可以剪裁
intent.putExtra("crop", "true");
// 设置不能改变裁减大小框
intent.putExtra("scale", true);
// aspectX aspectY 是宽高的比例
intent.putExtra("aspectX", 1);
intent.putExtra("aspectY", 1);
// outputX,outputY 是剪裁图片的宽高
intent.putExtra("outputX", 600);
intent.putExtra("outputY", 600);
// true:不返回uri,false:返回uri
intent.putExtra("return-data", false);
//保存裁剪的图片文件,在onActivityResult中返回的bitmap是个小的缩略图,三星测试的时候返回160*160的。
//所有这里使用File保存,如知道原因或本人代码bug,请告知。谢谢。
intent.putExtra("output", Uri.fromFile(tempFile));
startActivityForResult(intent, REQUEST_CUT_PHOTO_SIZE);
}
好了,通过上面的3段说明,已经可以在app中完成经常看到的需求了。
这个时候,你发现自己刚才拍的图片很不错,分享到朋友圈吧,让大家瞅瞅,然后打开微信,死活找不到这张图片,那是因为我们再onActivityResult中没有处理。在拍完照后,需要进行刷新。
/**
* 触发系统的Media Scanner,将我们的照片添加到Media Provider的数据库中,
* 这样就可以使得Android相册程序与其他程序能够读取到这些照片
*/
private void galleryAddPic() {
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
File f = new File(mCurrentPhotoPath);
Uri contentUri = Uri.fromFile(f);
mediaScanIntent.setData(contentUri);
this.sendBroadcast(mediaScanIntent);
}
1:图片需要进行缩放操作,避免OOM。
2:网上有的说,在图库选择图片的时候,可以直接传递缩放的intent参数,在三星note3上,可以正常使用,但是在mx4的测试中,却出现了问题,不能正常打开裁剪界面,最后还是还拍照一样处理,就OK了。
3:startActivityForResult中,requestCode不能小于0,如果小于0,是不会调用onActivityResult方法的。
4:不要忘记清单文件中权限的添加,对内存卡进行了操作。
最后,附上一个.java的代码,里面包含了上面的代码,没有整个工程。Android调用系统的相机,图库,以及裁剪图片功能。