android完美实现 拍照 选择图片 剪裁等代码分享
程序员文章站
2023-12-19 17:25:40
前言,版本兼容问题主要是由于4.4以前和4.4以后的uri的格式不同所造成的错误
1.拍照 和选择图片
①选择图片
intent = n...
前言,版本兼容问题主要是由于4.4以前和4.4以后的uri的格式不同所造成的错误
1.拍照 和选择图片
①选择图片
intent = new intent(intent.action_get_content); intent.settype("image/*"); startactivityforresult(intent, gallery_request_code);
②拍照
intent = new intent(mediastore.action_image_capture); startactivityforresult(intent, camera_request_code);
2.获取系统传来的值
标记符
private static int camera_request_code = 1; private static int gallery_request_code = 2; private static int crop_request_code = 3; @override protected void onactivityresult(int requestcode, int resultcode, intent data) { if (requestcode == camera_request_code) { if (data == null) { return; } else { //拍照 bundle extras = data.getextras(); if (extras != null) { bitmap bm = extras.getparcelable("data"); uri uri = savebitmap(bm); startimagezoom(uri); } } } else if (requestcode == gallery_request_code) { if (data == null) {//相册 return; } uri uri; uri = data.getdata(); uri fileuri = converturi(uri); startimagezoom(fileuri); } else if (requestcode == crop_request_code) { if (data == null) { return; }//剪裁后的图片 bundle extras = data.getextras(); if (extras == null) { return; } bitmap bm = extras.getparcelable("data"); showimageview(bm); } }
3.图片选取后 根据url 转成流 并保存
private uri converturi(uri uri) { inputstream is = null; try { is = getcontentresolver().openinputstream(uri); bitmap bitmap = bitmapfactory.decodestream(is); is.close(); return savebitmap(bitmap); } catch (filenotfoundexception e) { e.printstacktrace(); return null; } catch (ioexception e) { e.printstacktrace(); return null; } }
4.保存图片 记得加权限
private uri savebitmap(bitmap bm) { file tmpdir = new file(environment.getexternalstoragedirectory() + "/xiaoxin"); if (!tmpdir.exists()) { tmpdir.mkdir(); } file img = new file(tmpdir.getabsolutepath() + "love.png"); try { fileoutputstream fos = new fileoutputstream(img); bm.compress(bitmap.compressformat.png, 85, fos); fos.flush(); fos.close(); toast.maketext(mainactivity.this, "成功了", toast.length_short).show(); return uri.fromfile(img); } catch (filenotfoundexception e) { toast.maketext(mainactivity.this, "失敗了", toast.length_short).show(); e.printstacktrace(); return null; } catch (ioexception e) { e.printstacktrace(); toast.maketext(mainactivity.this, "失敗了", toast.length_short).show(); return null; } }
5.剪裁图片
/** * 剪裁图片 * * @param uri */ private void startimagezoom(uri uri) { intent intent = new intent("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
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.cogent.piccut" android:versioncode="1" android:versionname="1.0" > <uses-sdk android: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 > <action android:name="android.intent.action.main" /> <category android:name="android.intent.category.launcher" /> </intent-filter> </activity> </application> </manifest>
—————————————————————————————————————————————————
java代码:
package com.cogent.piccut; import java.io.file; import java.text.simpledateformat; import java.util.date; import android.app.activity; import android.app.alertdialog; import android.content.dialoginterface; import android.content.intent; import android.graphics.bitmap; import android.graphics.drawable.bitmapdrawable; import android.graphics.drawable.drawable; import android.net.uri; import android.os.bundle; import android.os.environment; import android.provider.mediastore; import android.view.view; import android.view.view.onclicklistener; import android.widget.button; import android.widget.imagebutton; public class piccutactivity extends activity implements onclicklistener { private imagebutton img_btn; private button btn; private static final int photo_request_takephoto = 1;// 拍照 private static final int photo_request_gallery = 2;// 从相册中选择 private static final int photo_request_cut = 3;// 结果 // 创建一个以当前时间为名称的文件 file tempfile = new file(environment.getexternalstoragedirectory(),getphotofilename()); /** called when the activity is first created. */ @override public void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.main); init(); } //初始化控件 private void init() { img_btn = (imagebutton) findviewbyid(r.id.img_btn); btn = (button) findviewbyid(r.id.btn); //为imagebutton和button添加监听事件 img_btn.setonclicklistener(this); btn.setonclicklistener(this); } //点击事件 @override public void onclick(view v) { // todo auto-generated method stub switch (v.getid()) { case r.id.img_btn: showdialog(); break; case r.id.btn: showdialog(); break; } } //提示对话框方法 private void showdialog() { new alertdialog.builder(this) .settitle("头像设置") .setpositivebutton("拍照", new dialoginterface.onclicklistener() { @override public void onclick(dialoginterface dialog, int which) { // todo auto-generated method stub dialog.dismiss(); // 调用系统的拍照功能 intent intent = new intent(mediastore.action_image_capture); // 指定调用相机拍照后照片的储存路径 intent.putextra(mediastore.extra_output,uri.fromfile(tempfile)); startactivityforresult(intent, photo_request_takephoto); } }) .setnegativebutton("相册", new dialoginterface.onclicklistener() { @override public void onclick(dialoginterface dialog, int which) { // todo auto-generated method stub dialog.dismiss(); intent intent = new intent(intent.action_pick, null); intent.setdataandtype(mediastore.images.media.external_content_uri,"image/*"); startactivityforresult(intent, photo_request_gallery); } }).show(); } @override protected void onactivityresult(int requestcode, int resultcode, intent data) { // todo auto-generated method stub switch (requestcode) { case photo_request_takephoto: startphotozoom(uri.fromfile(tempfile), 150); break; case photo_request_gallery: if (data != null) startphotozoom(data.getdata(), 150); break; case photo_request_cut: if (data != null) setpictoview(data); break; } super.onactivityresult(requestcode, resultcode, data); } private void startphotozoom(uri uri, int size) { intent intent = new intent("com.android.camera.action.crop"); intent.setdataandtype(uri, "image/*"); // crop为true是设置在开启的intent中设置显示的view可以剪裁 intent.putextra("crop", "true"); // aspectx aspecty 是宽高的比例 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界面上 private void setpictoview(intent picdata) { bundle bundle = picdata.getextras(); if (bundle != null) { bitmap photo = bundle.getparcelable("data"); drawable drawable = new bitmapdrawable(photo); img_btn.setbackgrounddrawable(drawable); } } // 使用系统当前日期加以调整作为照片的名称 private string getphotofilename() { date date = new date(system.currenttimemillis()); simpledateformat dateformat = new simpledateformat("'img'_yyyymmdd_hhmmss"); return dateformat.format(date) + ".jpg"; } }
心得总结:androi系统内部自带了图片的剪裁功能,开发是只要调用即可,intent的很多用法比较实用,但是太多了,需要用到的时候去查询或者平时多看看官方文档,很多代码看着简单但还是要实际自己去写更好些,理解的更深入一些。