android完美实现 拍照 选择图片 剪裁等代码分享
前言,版本兼容问题主要是由于4.4以前和4.4以后的Uri的格式不同所造成的错误
1.拍照和选择图片
①选择图片
intent=newIntent(Intent.ACTION_GET_CONTENT);
intent.setType("image/*");
startActivityForResult(intent,GALLERY_REQUEST_CODE);
②拍照
intent=newIntent(MediaStore.ACTION_IMAGE_CAPTURE); startActivityForResult(intent,CAMERA_REQUEST_CODE);
2.获取系统传来的值
标记符
privatestaticintCAMERA_REQUEST_CODE=1;
privatestaticintGALLERY_REQUEST_CODE=2;
privatestaticintCROP_REQUEST_CODE=3;
@Override
protectedvoidonActivityResult(intrequestCode,intresultCode,Intentdata){
if(requestCode==CAMERA_REQUEST_CODE){
if(data==null){
return;
}else{//拍照
Bundleextras=data.getExtras();
if(extras!=null){
Bitmapbm=extras.getParcelable("data");
Uriuri=saveBitmap(bm);
startImageZoom(uri);
}
}
}elseif(requestCode==GALLERY_REQUEST_CODE){
if(data==null){//相册
return;
}
Uriuri;
uri=data.getData();
UrifileUri=convertUri(uri);
startImageZoom(fileUri);
}elseif(requestCode==CROP_REQUEST_CODE){
if(data==null){
return;
}//剪裁后的图片
Bundleextras=data.getExtras();
if(extras==null){
return;
}
Bitmapbm=extras.getParcelable("data");
ShowImageView(bm);
}
}
3.图片选取后根据Url转成流并保存
privateUriconvertUri(Uriuri){
InputStreamis=null;
try{
is=getContentResolver().openInputStream(uri);
Bitmapbitmap=BitmapFactory.decodeStream(is);
is.close();
returnsaveBitmap(bitmap);
}catch(FileNotFoundExceptione){
e.printStackTrace();
returnnull;
}catch(IOExceptione){
e.printStackTrace();
returnnull;
}
}
4.保存图片记得加权限
privateUrisaveBitmap(Bitmapbm){
FiletmpDir=newFile(Environment.getExternalStorageDirectory()
+"/xiaoxin");
if(!tmpDir.exists()){
tmpDir.mkdir();
}
Fileimg=newFile(tmpDir.getAbsolutePath()+"love.png");
try{
FileOutputStreamfos=newFileOutputStream(img);
bm.compress(Bitmap.CompressFormat.PNG,85,fos);
fos.flush();
fos.close();
Toast.makeText(MainActivity.this,"成功了",Toast.LENGTH_SHORT).show();
returnUri.fromFile(img);
}catch(FileNotFoundExceptione){
Toast.makeText(MainActivity.this,"失敗了",Toast.LENGTH_SHORT).show();
e.printStackTrace();
returnnull;
}catch(IOExceptione){
e.printStackTrace();
Toast.makeText(MainActivity.this,"失敗了",Toast.LENGTH_SHORT).show();
returnnull;
}
}
5.剪裁图片
/**
*剪裁图片
*
*@paramuri
*/
privatevoidstartImageZoom(Uriuri){
Intentintent=newIntent("com.android.camera.action.CROP");
intent.setDataAndType(uri,"image/*");
intent.putExtra("crop","true");
intent.putExtra("aspectX",1);
intent.putExtra("aspectY",1);
intent.putExtra("outputX",150);
intent.putExtra("outputY",150);
intent.putExtra("return-data",true);
startActivityForResult(intent,CROP_REQUEST_CODE);
}
下面我们再来看一个实例:先是代码的部分,部分是从网路上摘录的,自己整理后当做工具类使用
配置文件:布局很简单,一个ImageButton和一个Button,点击都可以实现图像选择的功能,具体的实现根据大家在实际中用的效果而定
—————————————————————————————————————————————————
AndroidManifest.xml
<?xmlversion="1.0"encoding="utf-8"?> <manifestxmlns:android="http://schemas.android.com/apk/res/android" package="com.cogent.piccut" android:versionCode="1" android:versionName="1.0"> <uses-sdkandroid:minSdkVersion="10"/> <application android:icon="@drawable/ic_launcher" android:label="@string/app_name"> <activity android:label="@string/app_name" android:name=".PicCutActivity" android:screenOrientation="portrait"> <intent-filter> <actionandroid:name="android.intent.action.MAIN"/> <categoryandroid:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity> </application> </manifest>
—————————————————————————————————————————————————
Java代码:
packagecom.cogent.piccut;
importjava.io.File;
importjava.text.SimpleDateFormat;
importjava.util.Date;
importandroid.app.Activity;
importandroid.app.AlertDialog;
importandroid.content.DialogInterface;
importandroid.content.Intent;
importandroid.graphics.Bitmap;
importandroid.graphics.drawable.BitmapDrawable;
importandroid.graphics.drawable.Drawable;
importandroid.net.Uri;
importandroid.os.Bundle;
importandroid.os.Environment;
importandroid.provider.MediaStore;
importandroid.view.View;
importandroid.view.View.OnClickListener;
importandroid.widget.Button;
importandroid.widget.ImageButton;
publicclassPicCutActivityextendsActivityimplementsOnClickListener{
privateImageButtonimg_btn;
privateButtonbtn;
privatestaticfinalintPHOTO_REQUEST_TAKEPHOTO=1;//拍照
privatestaticfinalintPHOTO_REQUEST_GALLERY=2;//从相册中选择
privatestaticfinalintPHOTO_REQUEST_CUT=3;//结果
//创建一个以当前时间为名称的文件
FiletempFile=newFile(Environment.getExternalStorageDirectory(),getPhotoFileName());
/**Calledwhentheactivityisfirstcreated.*/
@Override
publicvoidonCreate(BundlesavedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
init();
}
//初始化控件
privatevoidinit(){
img_btn=(ImageButton)findViewById(R.id.img_btn);
btn=(Button)findViewById(R.id.btn);
//为ImageButton和Button添加监听事件
img_btn.setOnClickListener(this);
btn.setOnClickListener(this);
}
//点击事件
@Override
publicvoidonClick(Viewv){
//TODOAuto-generatedmethodstub
switch(v.getId()){
caseR.id.img_btn:
showDialog();
break;
caseR.id.btn:
showDialog();
break;
}
}
//提示对话框方法
privatevoidshowDialog(){
newAlertDialog.Builder(this)
.setTitle("头像设置")
.setPositiveButton("拍照",newDialogInterface.OnClickListener(){
@Override
publicvoidonClick(DialogInterfacedialog,intwhich){
//TODOAuto-generatedmethodstub
dialog.dismiss();
//调用系统的拍照功能
Intentintent=newIntent(MediaStore.ACTION_IMAGE_CAPTURE);
//指定调用相机拍照后照片的储存路径
intent.putExtra(MediaStore.EXTRA_OUTPUT,Uri.fromFile(tempFile));
startActivityForResult(intent,PHOTO_REQUEST_TAKEPHOTO);
}
})
.setNegativeButton("相册",newDialogInterface.OnClickListener(){
@Override
publicvoidonClick(DialogInterfacedialog,intwhich){
//TODOAuto-generatedmethodstub
dialog.dismiss();
Intentintent=newIntent(Intent.ACTION_PICK,null);
intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,"image/*");
startActivityForResult(intent,PHOTO_REQUEST_GALLERY);
}
}).show();
}
@Override
protectedvoidonActivityResult(intrequestCode,intresultCode,Intentdata){
//TODOAuto-generatedmethodstub
switch(requestCode){
casePHOTO_REQUEST_TAKEPHOTO:
startPhotoZoom(Uri.fromFile(tempFile),150);
break;
casePHOTO_REQUEST_GALLERY:
if(data!=null)
startPhotoZoom(data.getData(),150);
break;
casePHOTO_REQUEST_CUT:
if(data!=null)
setPicToView(data);
break;
}
super.onActivityResult(requestCode,resultCode,data);
}
privatevoidstartPhotoZoom(Uriuri,intsize){
Intentintent=newIntent("com.android.camera.action.CROP");
intent.setDataAndType(uri,"image/*");
//crop为true是设置在开启的intent中设置显示的view可以剪裁
intent.putExtra("crop","true");
//aspectXaspectY是宽高的比例
intent.putExtra("aspectX",1);
intent.putExtra("aspectY",1);
//outputX,outputY是剪裁图片的宽高
intent.putExtra("outputX",size);
intent.putExtra("outputY",size);
intent.putExtra("return-data",true);
startActivityForResult(intent,PHOTO_REQUEST_CUT);
}
//将进行剪裁后的图片显示到UI界面上
privatevoidsetPicToView(Intentpicdata){
Bundlebundle=picdata.getExtras();
if(bundle!=null){
Bitmapphoto=bundle.getParcelable("data");
Drawabledrawable=newBitmapDrawable(photo);
img_btn.setBackgroundDrawable(drawable);
}
}
//使用系统当前日期加以调整作为照片的名称
privateStringgetPhotoFileName(){
Datedate=newDate(System.currentTimeMillis());
SimpleDateFormatdateFormat=newSimpleDateFormat("'IMG'_yyyyMMdd_HHmmss");
returndateFormat.format(date)+".jpg";
}
}
心得总结:Androi系统内部自带了图片的剪裁功能,开发是只要调用即可,Intent的很多用法比较实用,但是太多了,需要用到的时候去查询或者平时多看看官方文档,很多代码看着简单但还是要实际自己去写更好些,理解的更深入一些。