Android获取本地相册图片和拍照获取图片的实现方法
程序员文章站
2023-12-06 16:49:28
需求:从本地相册找图片,或通过调用系统相机拍照得到图片。
容易出错的地方:
1、当我们指定了照片的uri路径,我们就不能通过data.getdata();来获取uri,...
需求:从本地相册找图片,或通过调用系统相机拍照得到图片。
容易出错的地方:
1、当我们指定了照片的uri路径,我们就不能通过data.getdata();来获取uri,而应该直接拿到uri(用全局变量或者其他方式)然后设置给imageview
imageview.setimageuri(uri);
2、我发现手机前置摄像头拍出来的照片只有几百kb,直接用imageview.setimageuri(uri);没有很大问题,但是后置摄像头拍出来的照片比较大,这个时候使用imageview.setimageuri(uri);就容易出现 out of memory(oom)错误,我们需要先把uri转换为bitmap,再压缩bitmap,然后通过imageview.setimagebitmap(bitmap);来显示图片。
3、将照片存放到sd卡中后,照片不能立即出现在系统相册中,因此我们需要发送广播去提醒相册更新照片。
4、这里用到了sharepreference,要注意用完之后移除缓存。
代码:
mainactivity:
package com.sctu.edu.test; import android.content.intent; import android.graphics.bitmap; import android.graphics.bitmapfactory; import android.net.uri; import android.os.bundle; import android.os.environment; import android.provider.mediastore; import android.support.v7.app.appcompatactivity; import android.util.log; import android.view.view; import android.widget.imageview; import com.sctu.edu.test.tools.imagetools; import java.io.file; import java.io.ioexception; import java.text.simpledateformat; import java.util.date; public class mainactivity extends appcompatactivity { private static final int photo_from_gallery = 1; private static final int photo_from_camera = 2; private imageview imageview; private file appdir; private uri uriforcamera; private date date; private string str = ""; private sharepreference sharepreference; @override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_main); //android不推荐使用全局变量,我在这里使用了sharepreference sharepreference = sharepreference.getinstance(this); imageview = (imageview) findviewbyid(r.id.imageview); } //从相册取图片 public void gallery(view view) { intent intent = new intent(); intent.settype("image/*"); intent.setaction(intent.action_get_content); startactivityforresult(intent, photo_from_gallery); } //拍照取图片 public void camera(view view) { intent intent = new intent(mediastore.action_image_capture); uriforcamera = uri.fromfile(createimagestoragepath()); sharepreference.setcache("uri", string.valueof(uriforcamera)); /** * 指定了uri路径,startactivityforresult不返回intent, * 所以在onactivityresult()中不能通过data.getdata()获取到uri; */ intent.putextra(mediastore.extra_output, uriforcamera); startactivityforresult(intent, photo_from_camera); } @override protected void onactivityresult(int requestcode, int resultcode, intent data) { super.onactivityresult(requestcode, resultcode, data); //第一层switch switch (requestcode) { case photo_from_gallery: //第二层switch switch (resultcode) { case result_ok: if (data != null) { uri uri = data.getdata(); imageview.setimageuri(uri); } break; case result_canceled: break; } break; case photo_from_camera: if (resultcode == result_ok) { uri uri = uri.parse(sharepreference.getstring("uri")); updatedcim(uri); try { //把uri转换为bitmap,并将bitmap压缩,防止oom(out of memory) bitmap bitmap = imagetools.getbitmapfromuri(uri, this); imageview.setimagebitmap(bitmap); } catch (ioexception e) { e.printstacktrace(); } removecache("uri"); } else { log.e("result", "is not ok" + resultcode); } break; default: break; } } /** * 设置相片存放路径,先将照片存放到sd卡中,再操作 * * @return */ private file createimagestoragepath() { if (hassdcard()) { appdir = new file("/sdcard/testimage/"); if (!appdir.exists()) { appdir.mkdirs(); } simpledateformat simpledateformat = new simpledateformat("yyyymmddhhmmss"); date = new date(); str = simpledateformat.format(date); string filename = str + ".jpg"; file file = new file(appdir, filename); return file; } else { log.e("sd", "is not load"); return null; } } /** * 将照片插入系统相册,提醒相册更新 * * @param uri */ private void updatedcim(uri uri) { intent intent = new intent(intent.action_media_scanner_scan_file); intent.setdata(uri); this.sendbroadcast(intent); bitmap bitmap = bitmapfactory.decodefile(uri.getpath()); mediastore.images.media.insertimage(getcontentresolver(), bitmap, "", ""); } /** * 判断sd卡是否可用 * * @return */ private boolean hassdcard() { if (environment.getexternalstoragestate().equals(environment.media_mounted)) { return true; } else { return false; } } /** * 移除缓存 * * @param cache */ private void removecache(string cache) { if (sharepreference.ifhaveshare(cache)) { sharepreference.removeonecache(cache); } else { log.e("this cache", "is not exist."); } } }
imagetools:
package com.sctu.edu.test.tools; import android.app.activity; import android.graphics.bitmap; import android.graphics.bitmapfactory; import android.net.uri; import java.io.bytearrayinputstream; import java.io.bytearrayoutputstream; import java.io.filenotfoundexception; import java.io.ioexception; import java.io.inputstream; public class imagetools { /** * 通过uri获取图片并进行压缩 * * @param uri * @param activity * @return * @throws ioexception */ public static bitmap getbitmapfromuri(uri uri, activity activity) throws ioexception { inputstream inputstream = activity.getcontentresolver().openinputstream(uri); bitmapfactory.options options = new bitmapfactory.options(); options.injustdecodebounds = true; options.indither = true; options.inpreferredconfig = bitmap.config.argb_8888; bitmapfactory.decodestream(inputstream, null, options); inputstream.close(); int originalwidth = options.outwidth; int originalheight = options.outheight; if (originalwidth == -1 || originalheight == -1) { return null; } float height = 800f; float width = 480f; int be = 1; //be=1表示不缩放 if (originalwidth > originalheight && originalwidth > width) { be = (int) (originalwidth / width); } else if (originalwidth < originalheight && originalheight > height) { be = (int) (originalheight / height); } if (be <= 0) { be = 1; } bitmapfactory.options bitmapoptinos = new bitmapfactory.options(); bitmapoptinos.insamplesize = be; bitmapoptinos.indither = true; bitmapoptinos.inpreferredconfig = bitmap.config.argb_8888; inputstream = activity.getcontentresolver().openinputstream(uri); bitmap bitmap = bitmapfactory.decodestream(inputstream, null, bitmapoptinos); inputstream.close(); return compressimage(bitmap); } /** * 质量压缩方法 * * @param bitmap * @return */ public static bitmap compressimage(bitmap bitmap) { bytearrayoutputstream bytearrayoutputstream = new bytearrayoutputstream(); bitmap.compress(bitmap.compressformat.jpeg, 100, bytearrayoutputstream); int options = 100; while (bytearrayoutputstream.tobytearray().length / 1024 > 100) { bytearrayoutputstream.reset(); //第一个参数 :图片格式 ,第二个参数: 图片质量,100为最高,0为最差 ,第三个参数:保存压缩后的数据的流 bitmap.compress(bitmap.compressformat.jpeg, options, bytearrayoutputstream); options -= 10; } bytearrayinputstream bytearrayinputstream = new bytearrayinputstream(bytearrayoutputstream.tobytearray()); bitmap bitmapimage = bitmapfactory.decodestream(bytearrayinputstream, null, null); return bitmapimage; } }
androidmainfest.xml:
<?xml version="1.0" encoding="utf-8"?> <manifest package="com.sctu.edu.test" xmlns:android="http://schemas.android.com/apk/res/android"> <uses-feature android:name="android.hardware.camera" android:required="true" /> <uses-permission android:name="android.permission.write_external_storage"/> <uses-permission android:name="android.permission.camera"/> <uses-permission android:name="android.permission.mount_unmount_filesystems"/> <uses-permission android:name="com.miui.whetstone.permission.access_provider"/> <uses-permission android:name="android.permission.read_external_storage"/> <uses-feature android:name="android.hardware.camera.autofocus" /> <application android:allowbackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsrtl="true" android:theme="@style/apptheme"> <activity android:name=".mainactivity"> <intent-filter> <action android:name="android.intent.action.main"/> <category android:name="android.intent.category.launcher"/> </intent-filter> </activity> </application> </manifest>
activity_main.xml:
<?xml version="1.0" encoding="utf-8"?> <linearlayout 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:background="#fff" android:orientation="vertical" tools:context="com.sctu.edu.test.mainactivity"> <button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="从图库找图片" android:id="@+id/gallery" android:onclick="gallery" android:background="#ccc" android:textsize="20sp" android:padding="10dp" android:layout_marginleft="30dp" android:layout_margintop="40dp" /> <button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="拍照获取图片" android:id="@+id/camera" android:onclick="camera" android:background="#ccc" android:textsize="20sp" android:padding="10dp" android:layout_marginleft="30dp" android:layout_margintop="40dp" /> <imageview android:layout_width="300dp" android:layout_height="300dp" android:id="@+id/imageview" android:scaletype="fitxy" android:background="@mipmap/ic_launcher" android:layout_margintop="40dp" android:layout_marginleft="30dp" /> </linearlayout>
效果图:
或许有人会问,在android6.0上面怎么点击拍照就出现闪退,那是因为我设置的最高sdk版本大于23,而我现在还没对运行时权限做处理,也许我会在下一篇博客里处理这个问题。谢谢浏览,希望对你有帮助!
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。