据图片的uri获取图片

合集下载

registerforactivityresult的用法 -回复

registerforactivityresult的用法 -回复

registerforactivityresult的用法-回复registerForActivityResult的用法registerForActivityResult是Android Jetpack库中的一个类,用于在一个Activity中启动另一个Activity并接收结果。

它的使用非常方便,可以简化处理ActivityResult的流程。

下面将详细介绍registerForActivityResult的用法。

步骤一:添加依赖首先,在项目的build.gradle文件中,添加以下依赖:javaimplementation 'androidx.activity:activity-ktx:1.2.0'这样就可以使用ActivityResults API了。

步骤二:创建Contract对象接下来,我们需要创建一个Contract对象,用于指定要启动的Activity 和处理结果的回调函数。

例如,我们要启动一个从Gallery选择照片的Activity,并接收选择的照片的URI,可以这样创建Contract对象:javaval selectPhotoContract =registerForActivityResult(ActivityResultContracts.GetContent()) { uri: Uri? ->处理选择的照片URI}这里使用了ActivityResultContracts.GetContent(),表示启动一个从系统Gallery选择照片的Activity。

在回调函数中,我们可以获取到选择的照片的URI,并进行处理。

步骤三:启动Activity并接收结果接下来,我们可以在需要启动Activity并接收结果的地方调用unch()方法。

例如,我们可以在一个按钮的点击事件中启动选择照片的Activity:javafindViewById<Button>(R.id.btn_select_photo).setOnClickListener {unch("image/*")}这里的"image/*"表示只选择图片文件。

android中打开相机、打开相册进行图片的获取示例

android中打开相机、打开相册进行图片的获取示例

android中打开相机、打开相册进⾏图⽚的获取⽰例这⾥介绍在Android中实现相机调取、拍照⽚、获取照⽚、存储新路径等已经打开相册、选择照⽚等功能⾸先看⼀下界⾯,很简单配置读取内存卡和调⽤照相头的功能<!-- 使⽤⽹络权限 --><uses-permission android:name="android.permission.INTERNET"/><!-- 写sd卡的权限 --><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/><!-- 读sd卡权限 --><uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/><uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />下⾯是代码的主题public class TakePhotos extends Activity implementsandroid.view.View.OnClickListener {Button takePhoto;Bitmap photo;String picPath;Button capture;@Overrideprotected void onCreate(Bundle savedInstanceState) {// TODO Auto-generated method stubsuper.onCreate(savedInstanceState);setContentView(yout.activity_photo);takePhoto = (Button) findViewById(R.id.button1);capture = (Button) findViewById(R.id.capture);takePhoto.setOnClickListener(this);capture.setOnClickListener(this);}@Overridepublic void onClick(View viewid) {switch (viewid.getId()) {case R.id.button1: {// 打开相机String state = Environment.getExternalStorageState();// 获取内存卡可⽤状态if (state.equals(Environment.MEDIA_MOUNTED)) {// 内存卡状态可⽤Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");startActivityForResult(intent, 1);} else {// 不可⽤Toast.makeText(TakePhotos.this, "内存不可⽤", Toast.LENGTH_LONG).show();}break;}case R.id.capture: {// 打开相册// 打开本地相册Intent i = new Intent(Intent.ACTION_PICK,android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);// 设定结果返回startActivityForResult(i, 2);break;}default:break;}}@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) {// TODO Auto-generated method stubsuper.onActivityResult(requestCode, resultCode, data);if (data != null) {switch (requestCode) {// 两种⽅式获取拍好的图⽚if (data.getData() != null || data.getExtras() != null) { // 防⽌没有返回结果Uri uri = data.getData();if (uri != null) {this.photo = BitmapFactory.decodeFile(uri.getPath()); // 拿到图⽚}if (photo == null) {Bundle bundle = data.getExtras();if (bundle != null) {photo = (Bitmap) bundle.get("data");FileOutputStream fileOutputStream = null;try {// 获取 SD 卡根⽬录⽣成图⽚并String saveDir = Environment.getExternalStorageDirectory()+ "/dhj_Photos";// 新建⽬录File dir = new File(saveDir);if (!dir.exists())dir.mkdir();// ⽣成⽂件名SimpleDateFormat t = new SimpleDateFormat( "yyyyMMddssSSS");String filename = "MT" + (t.format(new Date()))+ ".jpg";// 新建⽂件File file = new File(saveDir, filename);// 打开⽂件输出流fileOutputStream = new FileOutputStream(file);// ⽣成图⽚⽂件press(pressFormat.JPEG,100, fileOutputStream);// 相⽚的完整路径this.picPath = file.getPath();ImageView imageView = (ImageView) findViewById(R.id.imageView1); imageView.setImageBitmap(this.photo);} catch (Exception e) {e.printStackTrace();} finally {if (fileOutputStream != null) {try {fileOutputStream.close();} catch (Exception e) {e.printStackTrace();}}}Toast.makeText(getApplicationContext(), "获取到了",Toast.LENGTH_SHORT).show();} else {Toast.makeText(getApplicationContext(), "找不到图⽚",Toast.LENGTH_SHORT).show();}}}break;case 2: {//打开相册并选择照⽚,这个⽅式选择单张// 获取返回的数据,这⾥是android⾃定义的Uri地址Uri selectedImage = data.getData();String[] filePathColumn = { MediaStore.Images.Media.DATA };// 获取选择照⽚的数据视图Cursor cursor = getContentResolver().query(selectedImage, filePathColumn, null, null, null);cursor.moveToFirst();// 从数据视图中获取已选择图⽚的路径int columnIndex = cursor.getColumnIndex(filePathColumn[0]);String picturePath = cursor.getString(columnIndex);cursor.close();// 将图⽚显⽰到界⾯上ImageView imageView = (ImageView) findViewById(R.id.imageView1); imageView.setImageBitmap(BitmapFactory.decodeFile(picturePath)); break;}default:}}}}注释的很详细,⾃⼰分析吧。

Android中Bitmap、File与Uri之间的简单记录

Android中Bitmap、File与Uri之间的简单记录

Android中Bitmap、File与Uri之间的简单记录简介:感觉Uri 、File、bitmap ⽐较混乱,这⾥进⾏记载,⽅便以后查看.下⾯话不多说了,来⼀起看看详细的介绍吧Bitmap、File与Uri1、将⼀个⽂件路径path转换成FileString path ;File file = new File(path)2、讲⼀个Uri转换成⼀个path以选择⼀张图⽚为例:String path = FileTools.getRealPathFromUri(content,uri);//⾃定义⽅法在下⾯public static String getRealPathFromUri(Context context, Uri uri) {if (null == uri) return null; //传⼊的Uri为空,结束⽅法final String scheme = uri.getScheme(); //得到Uri的schemeString realPath = null;if (scheme == null)realPath = uri.getPath(); //如果scheme为空else if (ContentResolver.SCHEME_FILE.equals(scheme)) {realPath = uri.getPath(); //如果得到的scheme以file开头} else if (ContentResolver.SCHEME_CONTENT.equals(scheme)) {//得到的scheme以content开头Cursor cursor = context.getContentResolver().query(uri,new String[]{MediaStore.Images.ImageColumns.DATA},null, null, null);if (null != cursor) {if (cursor.moveToFirst()) {int index = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);if (index > -1) {realPath = cursor.getString(index);}}cursor.close(); //必须关闭}}//经过上⾯转换得到真实路径之后,判断⼀下这个路径,如果还是为空的话,说明有可能⽂件存在于外置sd卡上,不是内置sd卡.if (TextUtils.isEmpty(realPath)) {if (uri != null) {String uriString = uri.toString();int index = stIndexOf("/"); //匹配 / 在⼀个路径中最后出现位置String imageName = uriString.substring(index);//通过得到的最后⼀个位置,然后截取这个位置后⾯的字符串, 这样就可以得到⽂件名字了File storageDir;storageDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES); //查看外部储存卡公共照⽚的⽂件File file = new File(storageDir, imageName);//⾃⼰创建成⽂件,if (file.exists()) {realPath = file.getAbsolutePath();} else {// //那么存储在了外置sd卡的应⽤缓存file中storageDir = context.getExternalFilesDir(Environment.DIRECTORY_PICTURES);File file1 = new File(storageDir, imageName);realPath = file1.getAbsolutePath();}}}return realPath;⽐如我在android 8.0 上运⾏的时候选择照⽚之后的Uri : content://media/external/images/media/568344进⾏上⾯⽅法转换完之后: /storage/emulated/0/com.appben.appche/browser-photos/1550297407488.jpg}3、File 转换成pathString path = file.getPath();将此抽象路径名转换为⼀个路径名字符串。

onvif协议getsnapshoturi参数

onvif协议getsnapshoturi参数

ONVIF协议getSnapshotURI参数1.介绍在使用O NV IF(开放网络视频接口)协议进行视频流获取和控制时,g e tS na ps ho tU RI是一种非常常用的命令,用于获取摄像机实时画面的静态图片。

本文将详细介绍g et Sn ap sh ot U RI参数的使用方法和注意事项。

2.什么是get Snapsho tURI 参数g e tS na ps ho tU RI是O NV IF协议中的一个命令,用于获取摄像机的实时画面的静态图片的U RI(U ni fo rm Res o ur ce Id en ti fi er)。

通过该参数,我们可以访问摄像机的静态图片,实现获取相机当前画面的功能。

g e tS na ps ho tU RI命令是ON VI F协议的标准命令之一,几乎所有符合O N VI F标准的摄像机都支持该命令。

3.使用方法要使用g et Sn ap sh ot U RI命令,需要先建立与摄像机的网络连接,并确保摄像机支持O NVI F协议。

以下是使用g et Sn ap sh ot URI参数的基本步骤:3.1发送命令首先,我们需要向摄像机发送ge tS na psh o tU RI命令。

可以使用H T TP或者SO AP协议进行命令的发送。

3.2解析响应摄像机接收到ge tS na p sh ot UR I命令后,会返回一个响应,其中包含了静态图片的UR I。

我们需要解析该响应,提取出所需的U RI。

3.3访问图片通过获取到的UR I,我们可以使用HT TP或者其他协议,通过网络访问该静态图片。

可以使用常见的图像处理工具加载该图片,进行显示或者后续处理。

4.注意事项在使用g et Sn ap sh ot U RI参数时,需要注意以下几点:4.1权限控制某些摄像机可能会对g et Sn ap sh ot URI命令进行权限控制,只有具有足够权限的用户才能成功获取静态图片的U RI。

android系统通过图片绝对路径获取URI的三种方法

android系统通过图片绝对路径获取URI的三种方法

android系统通过图⽚绝对路径获取URI的三种⽅法最近做项⽬要通过图⽚的绝对路径找到图⽚的URI,然后删除图⽚,⼩⼩总结⼀下获取URI的⽅法,亲⾃试验在android 4.1.3的系统上都是可⽤的。

1.将所有的图⽚路径取出,遍历⽐较找到需要的路径,取出URI,效率较低其中 MediaStore.MediaColumns.DATA 字段存的就是图⽚的绝对路径,最后mImageUri得到的就是图⽚的URI1 Uri mUri = Uri.parse("content://media/external/images/media");2 Uri mImageUri = null;3 Cursor cursor = managedQuery(4 MediaStore.Images.Media.EXTERNAL_CONTENT_URI, null, null, null,5 MediaStore.Images.Media.DEFAULT_SORT_ORDER);6 cursor.moveToFirst();78while (!cursor.isAfterLast()) {9 String data = cursor.getString(cursor10 .getColumnIndex(MediaStore.MediaColumns.DATA));11if (picPath.equals(data)) {12int ringtoneID = cursor.getInt(cursor13 .getColumnIndex(MediaStore.MediaColumns._ID));14 mImageUri = Uri.withAppendedPath(mUri, "" + ringtoneID);15break;16 }17 cursor.moveToNext();18 }2.直接从媒体数据库根据字段取出相应的记录,效率较⾼1//TYLT: add by duanyf 20121027 start2 String type = Utils.ensureNotNull(intent.getType());3 Log.d(TAG, "uri is " + uri);4if (uri.getScheme().equals("file") && (type.contains("image/"))) {5 String path = uri.getEncodedPath();6 Log.d(TAG, "path1 is " + path);7if (path != null) {8 path = Uri.decode(path);9 Log.d(TAG, "path2 is " + path);10 ContentResolver cr = this.getContentResolver();11 StringBuffer buff = new StringBuffer();12 buff.append("(")13 .append(Images.ImageColumns.DATA)14 .append("=")15 .append("'" + path + "'")16 .append(")");17 Cursor cur = cr.query(18 Images.Media.EXTERNAL_CONTENT_URI,19new String[] { Images.ImageColumns._ID },20 buff.toString(), null, null);21int index = 0;22for (cur.moveToFirst(); !cur.isAfterLast(); cur23 .moveToNext()) {24 index = cur.getColumnIndex(Images.ImageColumns._ID);25// set _id value26 index = cur.getInt(index);27 }28if (index == 0) {29//do nothing30 } else {31 Uri uri_temp = Uri32 .parse("content://media/external/images/media/"33 + index);34 Log.d(TAG, "uri_temp is " + uri_temp);35if (uri_temp != null) {36 uri = uri_temp;37 }38 }39 }40 }41//TYLT: add by duanyf 20121027 end3.直接根据路径通过 ContentProvider 的 delete() ⽅法删除图⽚,两⾏代码搞定,效率最⾼1 String params[] = new String[]{filepath};2 ctx.getContentResolver().delete(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, MediaStore.Images.Media.DATA + " LIKE ?", params);PS:通过URI删除图⽚可以删除媒体库的信息和缩略图⼀并删除,不留痕迹,如果直接通过路径删除⽂件会删除不⼲净前两种⽅法获取的都是content开头的URI,还有⼀种file开头的URI,不知这两种有什么区别,望⼤神指教⼀⼆!。

课题_android系统通过图片绝对路径获取URI的三种方法

课题_android系统通过图片绝对路径获取URI的三种方法

最近做项目要通过图片的绝对路径找到图片的URI,然后删除图片,小小总结一下获取URI的方法,亲自试验在android 4.1.3的系统上都是可用的。

1.将所有的图片路径取出,遍历比较找到需要的路径,取出URI,效率较低其中 MediaStore.MediaColumns.DATA 字段存的就是图片的绝对路径,最后mImageUri得到的就是图片的URI1 Uri mUri = Uri.parse("content://media/external/images/media");2 Uri mImageUri = null;3 Cursor cursor = managedQuery(4 MediaStore.Images.Media.EXTERNAL_CONTENT_URI, null, null, null,5 MediaStore.Images.Media.DEFAULT_SORT_ORDER);6 cursor.moveToFirst();78while (!cursor.isAfterLast()) {9 String data = cursor.getString(cursor10 .getColumnIndex(MediaStore.MediaColumns.DATA)); 11if (picPath.equals(data)) {12int ringtoneID = cursor.getInt(cursor13 .getColumnIndex(MediaStore.MediaColumns._ ID));14 mImageUri = Uri.withAppendedPath(mUri, "" + ringtoneID); 15break;16 }17 cursor.moveToNext();18 }2.直接从媒体数据库根据字段取出相应的记录,效率较高1//TYLT: add by duanyf 20121027 start2 String type = Utils.ensureNotNull(intent.getType());3 Log.d(TAG, "uri is " + uri);4if (uri.getScheme().equals("file") && (type.contains("image/"))) {5 String path = uri.getEncodedPath();6 Log.d(TAG, "path1 is " + path);7if (path != null) {8 path = Uri.decode(path);9 Log.d(TAG, "path2 is " + path);10 ContentResolver cr = this.getContentResolver();11 StringBuffer buff = new StringBuffer();12 buff.append("(")13 .append(Images.ImageColumns.DATA)14 .append("=")15 .append("'" + path + "'")16 .append(")");17 Cursor cur = cr.query(18 Images.Media.EXTERNAL_CONTENT_URI,19new String[] { Images.ImageColumns._ID },20 buff.toString(), null, null);21int index = 0;22for (cur.moveToFirst(); !cur.isAfterLast(); cur23 .moveToNext()) {24 index = cur.getColumnIndex(Images.ImageColumns._ID);25// set _id value26 index = cur.getInt(index);27 }28if (index == 0) {29//do nothing30 } else {31 Uri uri_temp = Uri32 .parse("content://media/external/images/media/"33 + index);34 Log.d(TAG, "uri_temp is " + uri_temp);35if (uri_temp != null) {36 uri = uri_temp;37 }38 }39 }40 }41//TYLT: add by duanyf 20121027 end3.直接根据路径通过 ContentProvider 的 delete() 方法删除图片,两行代码搞定,效率最高1 String params[] = new String[]{filepath};2 ctx.getContentResolver().delete(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, MediaStore.Images.Media.DATA + " LIKE ?", params);PS:通过URI删除图片可以删除媒体库的信息和缩略图一并删除,不留痕迹,如果直接通过路径删除文件会删除不干净。

OpenAPI安全认证库(C#)V1.0.1开发指南(海康威视iSecure Center)

OpenAPI安全认证库(C#)V1.0.1开发指南(海康威视iSecure Center)
图 3.2.1-1 HttpUtillib 工程
2、 选择 Any CPU 模式下的平台。选择“生成”->“生成 HttpUtillib”(或英文模式下的“Build”->“Build HttpUtillib”),生成的 DLL 位于 bin 目录下。生成 HttpUtillib 以及生成结果如下图:
using HttpUtil
2、 设置平台信息参数
// 设置平台参数:合作方 APPKey、合作方 APPSecret、平台 IP、平台端口、以及是否适用 HTTPS 协议 // 只要平台信息参数一致,多个请求只需设置一次参数 HttpUtillib.SetPlatformInfo(“28730566”, “HSZkCJpSJ7gSUYrO6wVi”, "10.119.132.75", 443, true);
else
{
//// 注意:使用方应当知道哪个Uri返回的是字节流(如根据图片Url获取图片数据流),
////
哪个是返回字符串(请前往https:///docs软件产品的接口描述中查看),
////
如果肯定是返回字符串的,直接转成字符串即可;如果是返回字节流的,有可能因为请求失败
2/9
OpenAPI 安全认证库(C#)开发指南
使用此接口前需要设置平台信息,详见设置平台信息接口。
示例:
详见基于 OpenAPI 安全认证库(C#)接口的使用示例
2.3 GET 请求接口
接口名称: byte[] HttpGet(string uri, int timeout)
接口描述: 封装 HTTP/HTTPS GET 请求,提供 GET 请求统一入口。
////
了返回json报文,因此对于这种情况需要将字节流转换成字符串判断是否存在失败的情况,

Android获取本地相册图片和拍照获取图片的实现方法

Android获取本地相册图片和拍照获取图片的实现方法

Android获取本地相册图⽚和拍照获取图⽚的实现⽅法需求:从本地相册找图⽚,或通过调⽤系统相机拍照得到图⽚。

容易出错的地⽅:1、当我们指定了照⽚的uri路径,我们就不能通过data.getData();来获取uri,⽽应该直接拿到uri(⽤全局变量或者其他⽅式)然后设置给imageViewimageView.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 .test;import android.content.Intent;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import .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 .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;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(yout.activity_main);//Android不推荐使⽤全局变量,我在这⾥使⽤了sharePreferencesharePreference = 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);}@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) {super.onActivityResult(requestCode, resultCode, data);//第⼀层switchswitch (requestCode) {case PHOTO_FROM_GALLERY://第⼆层switchswitch (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 .test.tools;import android.app.Activity;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import .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();press(pressFormat.JPEG, 100, byteArrayOutputStream);int options = 100;while (byteArrayOutputStream.toByteArray().length / 1024 > 100) {byteArrayOutputStream.reset();//第⼀个参数:图⽚格式,第⼆个参数:图⽚质量,100为最⾼,0为最差,第三个参数:保存压缩后的数据的流 press(pressFormat.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=".test"xmlns:android="/apk/res/android"><uses-featureandroid: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" /><applicationandroid: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="UNCHER"/></intent-filter></activity></application></manifest>activity_main.xml:<?xml version="1.0" encoding="utf-8"?><LinearLayoutxmlns:android="/apk/res/android"xmlns:tools="/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:background="#fff"android:orientation="vertical"tools:context=".test.MainActivity"><Buttonandroid: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"/><Buttonandroid: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"/><ImageViewandroid: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,⽽我现在还没对运⾏时权限做处理,也许我会在下⼀篇博客⾥处理这个问题。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

Android相机、相册获取图片显示并保存到SD卡做过类似需求的同学都知道,在Activity中通过如下代码可以启动相机,然后在重写的onActivityResult方法中可以获取到返回的照片数据:Intent openCameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);startActivityForResult(openCameraIntent, TAKE_PICTURE);在onActivityResult方法里通过Intent的getData方法获取的数据转换成bitmap并显示在界面上,有时候会有取不到数据,或者显示的bitmap会非常小,如果将bitmap保存到sd卡后会发现,图片的分辨率很低,并且图片大小也是经过压缩的,不管将相机的像素设置多高,最后通过这种方式返回的bitmap总是经过压缩了的。

如果想获得理想的照片大小和分辨率改如何处理呢?大家都知道,现在手机像素少则500W或800W,多则4KW(某亚),就拿常见的800W像素的相机拍出来的照片来说,分辨率大概在3200*2400左右,照片大小在2M左右。

试想一下,在Android系统中bitmap占用4个字节,3200*2400*4=?,结果大家自己算算,如果为了一张图片,耗用这么大的内存,肯定是不合理的,并且,官方文档中有说明,Android系统分配给每个应用的最大内存是16M,所以,系统为了防止应用内存占用过大,对于在应用内通过相机拍摄的图片最终返回来的结果进行了压缩,压缩后的图片变得很小,通过之前说的getData的方式只能满足比如显示个头像这样的需求。

如果要显示大图,就会出现模糊的情况。

那如何获取清晰的大图呢?我的解决思路如下:1.拍照时,将拍得的照片先保存在本地,通过修改之前的代码如下:Uri imageUri = Uri.fromFile(new File(Environment.getExternalStorageDirectory(),"image.jpg"));//指定照片保存路径(SD卡),image.jpg为一个临时文件,每次拍照后这个图片都会被替换openCameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);如何调取相机拍照,代码如下:/**拍照获取相片**/private void doTakePhoto() {Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); //调用系统相机Uri imageUri = Uri.fromFile(new File(Environment.getExternalStorageDirectory(),"image.jpg"));//指定照片保存路径(SD卡),image.jpg为一个临时文件,每次拍照后这个图片都会被替换intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);//直接使用,没有缩小startActivityForResult(intent, PHOTO_WITH_CAMERA); //用户点击了从相机获取}2.在onActivityResult方法中再将图片取出,并经过缩小处理再显示在界面上或上传给服务器(压缩比例自定义)@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) {super.onActivityResult(requestCode, resultCode, data);if (resultCode == RESULT_OK) {switch (requestCode) {case TAKE_PICTURE://将保存在本地的图片取出并缩小后显示在界面上Bitmap bitmap = BitmapFactory.decodeFile(Environment.getExternalStorageDirectory()+"/ image.jpg");Bitmap newBitmap = zoomBitmap(bitmap, bitmap.getWidth() / SCALE, bitmap.getHeight() / SCALE);//由于Bitmap内存占用较大,这里需要回收内存,否则会报out of memory异常bitmap.recycle();//将处理过的图片显示在界面上,并保存到本地iv_image.setImageBitmap(newBitmap);savePhotoToSDCard(newBitmap,Environment.getExternalStorageDirectory().getAbsolutePath(),String.valueOf(System.currentTimeMillis()));break;default:break;}}}由于Android给bitmap分配的内存最大不超过8M,所以对使用完的较大的Bitmap要释放内存,调用其recycle()方法即可。

然后将缩小后的bitmap显示在界面上或保存到SD卡,至于之前保存的原图,可以删掉,也可以放在那,下次拍照时,这张原图就会被下一张照片覆盖,所以SD卡上使用只有一张临时图片,占用也不是很大。

以上讲的是拍照获取图片,如果是从相册中获取图片又如何处理呢,我的方法如下:1.打开相册选取图片:Intent openAlbumIntent = new Intent(Intent.ACTION_GET_CONTENT);openAlbumIntent.setType("image/*");startActivityForResult(openAlbumIntent,CHOOSE_PICTURE);2.在onActivity方法中处理获取到的图片,思路和之前类似@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) {super.onActivityResult(requestCode, resultCode, data);if (resultCode == RESULT_OK) {switch (requestCode) {case CHOOSE_PICTURE:ContentResolver resolver = getContentResolver();//照片的原始资源地址Uri originalUri = data.getData();try {//使用ContentProvider通过URI获取原始图片Bitmap photo = MediaStore.Images.Media.getBitmap(resolver, originalUri);if (photo != null) {//为防止原始图片过大导致内存溢出,这里先缩小原图显示,然后释放原始Bitmap占用的内存Bitmap smallBitmap = zoomBitmap(photo, photo.getWidth() / SCALE, photo.getHeight() / SCALE);//释放原始图片占用的内存,防止out of memory 异常发生photo.recycle();iv_image.setImageBitmap(smallBitmap);}} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}break;default:break;}}}还有一个方法zoomBitmap(),代码如下:/** 缩放Bitmap图片 **/public Bitmap zoomBitmap(Bitmap bitmap, int width, int height) {int w = bitmap.getWidth();int h = bitmap.getHeight();Matrix matrix = new Matrix();float scaleWidth = ((float) width / w);float scaleHeight = ((float) height / h);matrix.postScale(scaleWidth, scaleHeight);// 利用矩阵进行缩放不会造成内存溢出Bitmap newbmp = Bitmap.createBitmap(bitmap, 0, 0, w, h, matrix, true);return newbmp;}至此,功能已实现。

下面是本人项目中所实现的功能在这里总结一下:1.要想对从图库选择的照片进行裁剪:/**从相册获取图片**/private Intent doPickPhotoFromGallery() {Intent intent = new Intent();intent.setType("image/*"); // 开启Pictures画面Type设定为imageintent.setAction(Intent.ACTION_GET_CONTENT); //使用Intent.ACTION_GET_CONTENT这个Action//实现对图片的裁剪,必须要设置图片的属性和大小intent.setType("image/*"); //获取任意图片类型intent.putExtra("crop", "true"); //滑动选中图片区域intent.putExtra("aspectX", 1); //裁剪框比例1:1intent.putExtra("aspectY", 1);intent.putExtra("outputX", 300); //输出图片大小intent.putExtra("outputY", 300);intent.putExtra("return-data", true); //有返回值return intent;}调用此方法处:Intent intent2 = doPickPhotoFromGallery();startActivityForResult(intent2, PHOTO_WITH_DATA);ActivityForResult中和上面一样2.项目中要拍多少张就保存多少张,显示图片列表:A.将拍照的照片或者图库选择的图片,保存到本地创建图片名,不能重复哦!/** 为图片创建不同的名称用于保存,避免覆盖 **/public static String createFileName() {String fileName = "";Date date = new Date(System.currentTimeMillis()); // 系统当前时间 SimpleDateFormat dateFormat = new SimpleDateFormat("'IMG'_yyyyMMdd_HHmmss");fileName = dateFormat.format(date) + ".jpg";return fileName;}保存图片到SD卡/**Save image to the SD card**/public static void savePhotoToSDCard(String path, String photoName,Bitmap photoBitmap) {if (android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED)) {File dir = new File(path);if (!dir.exists()) {dir.mkdirs();}File photoFile = new File(path, photoName); //在指定路径下创建文件 FileOutputStream fileOutputStream = null;try {fileOutputStream = new FileOutputStream(photoFile);if (photoBitmap != null) {if (press(pressFormat.PNG, 100, fileOutputStream)) {fileOutputStream.flush();}}} catch (FileNotFoundException e) {photoFile.delete();e.printStackTrace();} catch (IOException e) {photoFile.delete();e.printStackTrace();} finally {try {fileOutputStream.close();} catch (IOException e) {e.printStackTrace();}}}}B.最后就是显示图片列表,因为我们要用到listView,自然少不了Adapter了,我们将保存到SD卡上的图片名获取到集合中,在自定义的适配器中根据名字加载图片喽!自定义图片列表适配器代码:/*** 插入图片列表适配器* @author ZHF**/public class ImagesListAdapter extends BaseAdapter {private Context context;private List<String> imagesList; //各个图片的路径public ImagesListAdapter(Context context, List<String> imagesList) { this.context = context;this.imagesList = imagesList;}/**得到总的数量**/@Overridepublic int getCount() {// TODO Auto-generated method stubreturn imagesList.size();}/**根据ListView位置返回View**/@Overridepublic Object getItem(int position) {return imagesList.get(position); //返回当前选中的item图片的路径}/**根据ListView位置得到List中的ID**/@Overridepublic long getItemId(int position) {// TODO Auto-generated method stubreturn position; //返回当前选中项的Id}/**根据位置得到View对象**/@Overridepublic View getView(int position, View convertView, ViewGroup parent) {if(convertView == null) {convertView = LayoutInflater.from(context).inflate(yout.newwrite_image_item, null);}ImageView img = (ImageView) convertView.findViewById(R.id.newwrite_et_content_image); //图片列表项if(!imagesList.get(position).equals("")) {//没有图片Bitmap tempBitmap = BitmapFactory.decodeFile(imagesList.get(position));//根据路径显示对应的图片Bitmap newBitmap = new ImageManager(context).zoomBitmap(tempBitmap, tempBitmap.getWidth(), tempBitmap.getHeight() / 3);img.setImageBitmap(newBitmap);//对应的行上显示对应的图片 }return convertView;}}。

相关文档
最新文档