Android拍照或从相册取得照片并裁剪
设计思路
两种方式获取图片:一种是拍照,另一种是从相册得到。因为重写了onActivityResult方法,每一个activity结束后都会调用上一个activity的onActivityResult方法把当前activity处理数据返回给上一个activity进行进一步的处理,返回的信息包括当前activity在上一个activity中的被调用处(用于对不同调用方法有不同的处理,比如有两个按钮会调用相同的activity,这时可以区分),当前activity信息(用于区分响应的不同activity,比如一个按钮调用多个activity),处理的结果数据。比如点击按钮触发拍照,拍照后会把图片存到本地,并且返回一个地址给前一个activity,前一个activity可以通过返回来的结果码对图片作进一步的处理,比如对图片进行裁剪,图片裁剪后的返回的结果码会告诉前一个activity应该对图片做最终处理了,即把它压缩为指定格式的图片保存并显示在界面上;又比如点击的是从相册获取图片,下一步就是对图片裁剪,最后是显示到MainActivity上。
代码实现
注:代码中的每一步都加上了注释,便于大家理解和使用。
xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<ImageView
android:id="@+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="161dp" />
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginBottom="65dp"
android:layout_toLeftOf="@+id/imageView1"
android:text="拍照" />
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="@+id/button1"
android:layout_alignBottom="@+id/button1"
android:layout_toRightOf="@+id/imageView1"
android:text="从相册选取" />
</RelativeLayout>
MainActivity:
public class MainActivity extends Activity {
private static final int NONE=0;
private static final String IMAGE_UNSPECIFIED="image/*";
private static final int PHOTOZOOM =2; //触发从图库获取图片的按钮
private static final int PHOTOSHOOT=1; //触发拍照获取图片的按钮
private static final int PHOTORESULT=3;//结果
private ImageView iView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btnShoot=(Button)findViewById(R.id.button1);
Button btnAlum=(Button)findViewById(R.id.button2);
iView=(ImageView)findViewById(R.id.imageView1);
btnAlum.setOnClickListener(new OnClickListener() {
//从图库获取照片
@Override
public void onClick(View v) {
Intent intent=new Intent(Intent.ACTION_PICK);//选择数据的意图
intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,IMAGE_UNSPECIFIED );//设置数据和类型,从图库中获取图片
startActivityForResult(intent, PHOTOZOOM);//执行意图并传入请求码(请求码根据业务需要自行指定)
}
});
btnShoot.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Intent intent =new Intent(MediaStore.ACTION_IMAGE_CAPTURE);//拍照到指定目录的意图
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File(Environment.getExternalStorageDirectory(),"temp.jpg")));//设置照片保存地址
startActivityForResult(intent, PHOTOSHOOT);//执行意图并传入请求码
}
});
}
/**
* 接收之前activity结束后返回的数据,并处理
*/
protected void onActivityResult(int requestCode,int resultCode,Intent data){
Log.v("test", "onActivityResult is: requestCode: "+requestCode+" resultCode: "+resultCode+" data: "+data);
//拍照和图库获取都需要有activity返回,拍照不需要data返回
if(resultCode==NONE){
return;
}
if(requestCode==PHOTOSHOOT){
File picture = new File(Environment.getExternalStorageDirectory()+"/temp.jpg");//获取之前拍照保存的照片地址
startPhotoZoom(Uri.fromFile(picture));//获取地址并调用裁剪
}
//若无数据,则没有从相册得到照片,直接返回
if(data==null)
return;
if(requestCode==PHOTOZOOM){
startPhotoZoom(data.getData());//返回的是地址,然后对图片裁剪
}
//如果得到的是结果图片,就显示出来,处理结果
if(requestCode==PHOTORESULT){
Bundle bundle=data.getExtras();//把数据取出来,Bundle是一个装数据的可以在activity之间传输的类
Bitmap bitmap =bundle.getParcelable("data");//获取位图
ByteArrayOutputStream stream=new ByteArrayOutputStream();//获取字节数组输出流
bitmap.compress(Bitmap.CompressFormat.JPEG,75,stream);//把图片在流中按照指定格式压缩
iView.setImageBitmap(bitmap);//设置位图,显示
}
super.onActivityResult(requestCode, resultCode, data);//使得参数传递到之前的activity
}
/**
* 照片压缩
* @param uri
*/
public void startPhotoZoom(Uri uri){
Intent intent =new Intent("com.android.camera.action.CROP");//裁剪意图
intent.setDataAndType(uri, IMAGE_UNSPECIFIED);//设置裁剪的地址和类型
intent.putExtra("crop", false);//把未裁剪信息附加到intent上
//设置宽高比例为1:1
intent.putExtra("aspectX", 1);
intent.putExtra("aspectY", 1);
//设置裁剪图片的宽高
intent.putExtra("return-data", true);//要返回值
startActivityForResult(intent, PHOTORESULT);//执行意图,赋予请求码
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
3、效果截图:
①选择拍照按钮:
②拍照后截图
③截图后显示在MainActivity
④选择相册按钮(后续步骤是②③,截图和显示)