今天,跟大家分享下如何在Android中实现调用系统相机、系统相册来获取图片的功能。
一、首先,讲解下调用相机原理:
1.调用系统相机很简单,通过Intent简单几行代码搞定,在调用相机时,为了获取拍下后的照片,我们需要创建一个File目录来保存,此处我们通过Environment来获取SD卡目录进行保存。
2.我们以系统时间命名图片名称,并创建一个临时的File。
3.调用Uri,fromFile(File file)方法,将步骤二中创建的File作为参数传进方法中。
4.将该Uri作为外部输出到SD卡。
5.调用startActivityForResult来开启相机。
二、调用相册原理:
我在上篇博客中讲解了两种调用相册的方式,在此不再多说,不知道的小伙伴,查看此处:http://blog.csdn.net/u013718120/article/details/49000673
三、获取数据,裁剪图片:
因为我们使用的是startActivityForResult,所以需要在Activity中实现onActivityResult(int requestCode, int resultCode, Intent data) 方法,在该方法中来获取数据:
1.首先,如果是调用相册,我们可以通过data.getData()来获取对应的Uri;如果是调用相机,需要将上面中Uri,fromFile(File file)的返回结果作为uri。
2.创建新的Intent,并设置参数。
3.调用startActivityForResult启动新的Intent。
4,.通过data.getParceableExtra("data");来获取裁剪后的图片,并进行设置。
好了,大致原理说清楚后,我们直接看代码:
import java.io.File;
import java.io.IOException;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.view.View;
import android.widget.ImageView;
import android.widget.Toast;
/**
*
* @author 宋小亮
*
*/
public class MainActivity extends Activity {
private ImageView iv_show;
private static final int TAKE_PHOTO_REQUEST_CODE = 0;//调用照相机
private static final int SELECT_PHOTO_REQUEST_CODE = 1;//从系统图库选择照片
private static final int CUT_PHOTO_REQUEST_CODE = 2;//裁剪图片
private static final String TEMP_TAKE_PHOTO_FILE_PATH = Environment.getExternalStorageDirectory().toString();
Uri tempUri;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initViews();
}
/**
* 初始化View
*/
private void initViews() {
iv_show = (ImageView)findViewById(R.id.iv_show);
}
/**
* 调用图库
* @param view
*/
public void skip(View view){
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
Intent wrapperIntent = Intent.createChooser(intent, null);
this.startActivityForResult(intent, SELECT_PHOTO_REQUEST_CODE);
}
/**
* 调用照相机
* @param view
*/
public void take(View view){
Intent takeIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File myImageDir = new File(TEMP_TAKE_PHOTO_FILE_PATH);
//创建图片保存目录
if(!myImageDir.exists()){
myImageDir.mkdirs();
}
//根据时间来命名
File imageFile = null;
try {
imageFile = File.createTempFile(""+System.currentTimeMillis(), ".jpg",myImageDir);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
tempUri = Uri.fromFile(imageFile);
takeIntent.putExtra(MediaStore.EXTRA_OUTPUT, tempUri);
startActivityForResult(takeIntent, TAKE_PHOTO_REQUEST_CODE);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if(requestCode == SELECT_PHOTO_REQUEST_CODE || requestCode == TAKE_PHOTO_REQUEST_CODE){
if(resultCode == Activity.RESULT_OK){
Uri uri = null;
if(requestCode == SELECT_PHOTO_REQUEST_CODE){
uri = data.getData();
}else if(requestCode == TAKE_PHOTO_REQUEST_CODE){
uri = tempUri;
}
//设置裁剪参数
if(uri != null){
Intent cutIntent = new Intent("com.android.camera.action.CROP");
cutIntent.setDataAndType(uri, "image/*");
cutIntent.putExtra("crop", "true");
cutIntent.putExtra("aspectX", 1);
cutIntent.putExtra("aspectY", 1);
cutIntent.putExtra("outputX", 132);
cutIntent.putExtra("outputY", 132);
cutIntent.putExtra("return-data", true);
startActivityForResult(cutIntent, CUT_PHOTO_REQUEST_CODE);
}
}
}else if(requestCode == CUT_PHOTO_REQUEST_CODE){
//获取裁剪的图片
if(resultCode == Activity.RESULT_OK && data != null){
if(data.hasExtra("data")){
Bitmap bm = data.getParcelableExtra("data");
iv_show.setImageBitmap(bm);
}else{
Toast.makeText(getApplicationContext(), "没有获取到数据!", Toast.LENGTH_LONG).show();
}
}
}
}
}
在裁剪图片时,遇到有些图片不能按照某一指定的比例进行裁剪,查看了源码后才知道:系统的裁剪图片默认对图片进行人脸识别,当识别到有人脸时,会按aspectX和aspectY为1来处理,如果想设置成自定义的裁剪比例,需要设置noFaceDetection为true。
即iintent.putExtra("noFaceDetection", true); 取消人脸识别功能。
本片博客部分参考:http://blog.csdn.net/junjieking/article/details/7164440