Android 拍照、从相册选择图片

简介: 在做Android图片上传功能的时候,获取图片的途径一般都有两种:拍照、从相册选择。一、拍照调用相机拍照有两种方法:直接返回图片。

在做Android图片上传功能的时候,获取图片的途径一般都有两种:拍照、从相册选择。


一、拍照

调用相机拍照有两种方法:

  1. 直接返回图片。
  2. 在调用相机的时候,传入uri,拍照后通过该uri来获取图片。

1.直接返回图片

private int TAKE_SMALL_PHOTO_REQUEST=0//全局变量

Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, TAKE_PHOTO_REQUEST);

  就是通过Intent发出隐式意图,制定action为MediaStore.ACTION_IMAGE_CAPTURE,来调用系统的相机。并返回相机拍的图片。在onActivityResult方法里接收。

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (resultCode == RESULT_CANCELED) {
        Toast.makeText(context, "拍照取消!", Toast.LENGTH_LONG).show();
        return;
    }
    if (resultCode == RESULT_OK) {
        switch (requestCode) {
            case TAKE_PHOTO_REQUEST:
                // 拍照返回结果
                Bitmap  photo = data.getParcelableExtra("data");
                // 按需求处理photo   

                break;
            }
     }
 }

  返回的图片以bitmap的格式存放在data的key值是“date”中。取出后可进行相应的操作,比如显示、保存、上传。但是,要注意的是这是返回的bitmap是被系统用默认压缩方式压缩过的图片。那么要想获取原图或用自己的压缩方式处理怎么办呢?就要用到方法二了。

2.在调用相机的时候,传入uri,拍照后通过该uri来获取图片

//全局变量
private int TAKE_BIG_PHOTO_REQUEST=1private Uri imageUri;

imageUri = createImageUri(context);//创建存储图片的uri,该方法见下边的讲解
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
startActivityForResult(intent, TAKE_BIG_PHOTO_REQUEST);

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (resultCode == RESULT_CANCELED) {
        deleteUri(imageUri, null, null);// 拍照取消,删除不用的文件
        Toast.makeText(context, "拍照取消!", Toast.LENGTH_LONG).show();
        return;
    }
    if (resultCode == RESULT_OK) {
        switch (requestCode) {
            case TAKE_BIG_PHOTO_REQUEST:
                // 直接使用之前新建的图片uri,来操作图片
                // 按需求处理photo,比如显示   
                iv.setImageURI(imageUri);
                break;
            }
     }
 }


  这种方法是向Intent中添加一条图片的uri数据,这时拍照完成后,系统会将图片存在这个uri中,在onActivityResult中,就可以直接使用这个uri操作图片了。隐式意图“MediaStore.ACTION_IMAGE_CAPTURE”和关键字“MediaStore.EXTRA_OUTPUT”也可以分别用“android.media.action.IMAGE_CAPTURE”和“output”代替。都是一个意思,只不过是不同的表示方法。

  删除文件方法deleteUri(imageUri, null, null),参考我的一篇博客Android 根据Uri删除文件里的两种删除方法,文章的最后有一个综合方法,不同的方法为了兼容下边创建存储图片、获取uri的两种不同的方法。

创建存储图片、获取uri
1. 方法一

private Uri createImageUri(Context context){
    Uri uri = null;
        if(Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())){
    String name = String.valueOf(System.currentTimeMillis());
    ContentValues contentValues = new ContentValues();
    contentValues.put(MediaStore.Images.Media.TITLE, name);
    contentValues.put(MediaStore.Images.Media.DISPLAY_NAME, name + ".jpeg");
    contentValues.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
    uri = context.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues);
    }

    return uri;
}

  创建文件和获取uri同时进行。
  首先将图片的文件信息保存在ContentValues 中,在通过ContentResolver类的insert方法来创建图片文件,并获取uri。该uri是以“content://”开头的,因此,可以用在Android 7.0以上版本。
  优点:简单。
  缺点:只能进行外部存储,存放图片的默认文件夹Pictures。原因是:
    insert方法创建时只有两种存储方式:
         1.EXTERNAL_CONTENT_URI,就是现在用的。
         2.INTERNAL_CONTENT_URI,指向的是内部存储的根目录,而我们是访问不了的,会报错。
  不熟悉外部存储和内部存储的小伙伴可以参考我的一篇博客Android内部存储与外部存储解析 希望对你有所帮助。
  从原因的分析看,这种方法只能存在手机有外部存储的时候可以用,不过现在手机基本上都实现了SD内置本身就可以外部存储,不用担心这个。但是如果开发需求需要,存放在指定的文件夹怎么办,那看方法二了。

2.方法二

 private Uri createImageUri(Context context,String myPath) {
     //创建文件
     String state = Environment.getExternalStorageState();
     File rootDir = state.equals(Environment.MEDIA_MOUNTED) ? Environment.getExternalStorageDirectory() : context.getCacheDir();
     File folderDir = new File(rootDir.getAbsolutePath() + myPath);//myPath是图片存放的自定义的路径

     if (!folderDir.exists() && folderDir.mkdirs()) {

     }

     String fileName = System.currentTimeMillis() + ".JPEG";
     File tmpFile = new File(folderDir, fileName);

     // 调用parUri方法转成uri
     return parUri(tmpFile);
 }

 /**
  * 生成uri
  * @param cameraFile
  * @return
  */
 private Uri parUri(File cameraFile) {
     Uri imageUri;
     String authority = context.getPackageName() + ".provider";
     if (Build.VERSION.SDK_INT > Build.VERSION_CODES.M) {
         //通过FileProvider创建一个content类型的Uri
         imageUri = FileProvider.getUriForFile(this, authority, cameraFile);
     } else {
         imageUri = Uri.fromFile(cameraFile);
     }
     return imageUri;
 }

  这种方法是我要实现一个图片选择器的时候,看到LuckSiege开源框架里的一个方法,也引发了我对FileProvider类的学习,之后对FileProvider进行总结。
创建文件和获取uri分两步:
1. rootDir是外部存储的根目录,第二个参数可以自定义路径,比如“/photoTest/”;当不能进行外部存储的时候,调用getCacheDir()放在应用的cache目录下。
2. 转成Uri,Uri.fromFile(cameraFile)方法,传化成Uri以file://开头,这时如果想调用系统剪裁或与其他应用进行通信,在Android 7.0以上就会报错闪退。就要在SDK版本大于24时,用FileProvider.getUriForFile(this, authority, cameraFile)方法,转化成Uri以content://开头,来适用Android7.0以上。如上边的方法parUri(File cameraFile)。FileProvider使用时需要配置一些东西,网上有很多讲解,文章末尾有一个包含有配置demo可以下载。
  这样就完美又灵活的实现了创建图片文件。

二、从相册获取

调用系统相册

Intent intent = new Intent();
intent.setAction(Intent.ACTION_PICK);              
intent.setData(MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(intent, TAKE_ALBUM_REQUEST);

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    MLog.e("resultCode" + resultCode);
    if (resultCode == RESULT_CANCELED) {
        ToastUtil.showMessage(mContext, "取消设置图片!");
    }
    if (resultCode == RESULT_OK) {
        switch (requestCode) {
            case TAKE_ALBUM_REQUEST:
                Uri uri = data.getData();// 获取选择图片的uri
                // 对uri进行处理

                break;

    }
}

  调用系统图片很简单,不过一般系统图片会非常大,直接显示的时候,会报OOM。需要先进行压缩或剪裁的处理。在压缩或剪裁之前注意创建一个新的文件,处理后保存在新的文件里,否则就会处理后的图就会覆盖原图片,并且有些手机覆盖原图的时候会报错。

通过拍照、相册获取图片demo

目录
相关文章
|
4月前
|
XML Android开发 数据格式
Android利用selector(选择器)实现图片动态点击效果
本文介绍了Android中ImageView的`src`与`background`属性的区别及应用,重点讲解如何通过设置背景选择器实现图片点击动态效果。`src`用于显示原图大小,不拉伸;`background`可随组件尺寸拉伸。通过创建`selector_setting.xml`,结合`setting_press.xml`和`setting_normal.xml`定义按下和正常状态的背景样式,提升用户体验。示例代码展示了具体实现步骤,包括XML配置和形状定义。
173 3
Android利用selector(选择器)实现图片动态点击效果
|
4月前
|
Java Android开发
Android图片的手动放大缩小
本文介绍了通过缩放因子实现图片放大缩小的功能,效果如动图所示。关键步骤包括:1) 在布局文件中设置 `android:scaleType="matrix"`;2) 实例化控件并用 `ScaleGestureDetector` 处理缩放手势;3) 使用 `Matrix` 对图片进行缩放处理。为避免内存崩溃,可在全局配置添加 `android:largeHeap="true"`。代码中定义了 `beforeScale` 和 `nowScale` 变量控制缩放范围,确保流畅体验。
137 8
|
4月前
|
缓存 编解码 Android开发
Android内存优化之图片优化
本文主要探讨Android开发中的图片优化问题,包括图片优化的重要性、OOM错误的成因及解决方法、Android支持的图片格式及其特点。同时介绍了图片储存优化的三种方式:尺寸优化、质量压缩和内存重用,并详细讲解了相关的实现方法与属性。此外,还分析了图片加载优化策略,如异步加载、缓存机制、懒加载等,并结合多级缓存流程提升性能。最后对比了几大主流图片加载框架(Universal ImageLoader、Picasso、Glide、Fresco)的特点与适用场景,重点推荐Fresco在处理大图、动图时的优异表现。这些内容为开发者提供了全面的图片优化解决方案。
149 1
|
12月前
|
存储 缓存 编解码
Android经典面试题之图片Bitmap怎么做优化
本文介绍了图片相关的内存优化方法,包括分辨率适配、图片压缩与缓存。文中详细讲解了如何根据不同分辨率放置图片资源,避免图片拉伸变形;并通过示例代码展示了使用`BitmapFactory.Options`进行图片压缩的具体步骤。此外,还介绍了Glide等第三方库如何利用LRU算法实现高效图片缓存。
159 20
Android经典面试题之图片Bitmap怎么做优化
|
数据处理 开发工具 数据安全/隐私保护
Android平台RTMP推送|轻量级RTSP服务|GB28181接入之文字、png图片水印的精进之路
本文探讨了Android平台上推流模块中添加文字与PNG水印的技术演进。自2015年起,为了满足应急指挥及安防领域的需求,逐步发展出三代水印技术:第一代为静态文字与图像水印;第二代实现了动态更新水印内容的能力,例如实时位置与时间信息;至第三代,则优化了数据传输效率,直接使用Bitmap对象传递水印数据至JNI层,减少了内存拷贝次数。这些迭代不仅提升了用户体验和技术效率,也体现了开发者追求极致与不断创新的精神。
143 7
|
自然语言处理 定位技术 API
Android经典实战之如何获取图片的经纬度以及如何根据经纬度获取对应的地点名称
本文介绍如何在Android中从图片提取地理位置信息并转换为地址。首先利用`ExifInterface`获取图片内的经纬度,然后通过`Geocoder`将经纬度转为地址。注意操作需在子线程进行且考虑多语言支持。
783 4
|
XML 前端开发 Android开发
Android经典实战之Kotlin中实现圆角图片和圆形图片
本文介绍两种实现圆角图像视图的方法。第一种是通过自定义Kotlin `AppCompatImageView`,重写`onDraw`方法使用`Canvas`和`Path`进行圆角剪裁。第二种利用Android Material库中的`ShapeableImageView`,简单配置即可实现圆角效果。两种方法均易于实现且提供动态调整圆角半径的功能。
222 0
|
Android开发
Android 拍照或相册剪裁后取头像
引用 1、Android7.0 头像 拍照、照片裁剪 2、联合使用:Android 仿IOS的PopupWindow和通用BasePopupWindow搭建 截图 crop_img.
1271 0
|
2月前
|
安全 数据库 Android开发
在Android开发中实现两个Intent跳转及数据交换的方法
总结上述内容,在Android开发中,Intent不仅是活动跳转的桥梁,也是两个活动之间进行数据交换的媒介。运用Intent传递数据时需注意数据类型、传输大小限制以及安全性问题的处理,以确保应用的健壯性和安全性。
119 11
|
6月前
|
JavaScript Linux 网络安全
Termux安卓终端美化与开发实战:从下载到插件优化,小白也能玩转Linux
Termux是一款安卓平台上的开源终端模拟器,支持apt包管理、SSH连接及Python/Node.js/C++开发环境搭建,被誉为“手机上的Linux系统”。其特点包括零ROOT权限、跨平台开发和强大扩展性。本文详细介绍其安装准备、基础与高级环境配置、必备插件推荐、常见问题解决方法以及延伸学习资源,帮助用户充分利用Termux进行开发与学习。适用于Android 7+设备,原创内容转载请注明来源。
1123 77

热门文章

最新文章