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的很多用法比较实用,但是太多了,需要用到的时候去查询或者平时多看看官方文档,很多代码看着简单但还是要实际自己去写更好些,理解的更深入一些。