如何从本地选择图片文件

使用Intent调用系统相册后,onActivityResult函数返回的是Uri格式的路径

/**
* 打开系统相册
*/
private void openSysAlbum() {
Intent innerIntent = new Intent();
if (Build.VERSION.SDK_INT < 19) {
innerIntent.setAction(Intent.ACTION_GET_CONTENT);
} else {
innerIntent.setAction(Intent.ACTION_OPEN_DOCUMENT);
}
innerIntent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");
Intent wrapperIntent = Intent.createChooser(innerIntent, "选择二维码图片");
startActivityForResult(wrapperIntent, SELECT_IMAGE_REQUEST_CODE);
} @Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case SELECT_IMAGE_REQUEST_CODE:
if (resultCode == RESULT_OK) {
Uri uri = data.getData();
scanningImage(uri);
}
break;
}
}

如何将Uri的路径转化为Bitmap

获取Bitmap现在我查到两种解决方案:

两种方案都可以,我感觉第二种方案更加靠谱一点,因为系统的数据库可能会更改,但是直接获取InputStream是不会变的。

第一种方案代码

/**
*
* @param intent
*/
public void ecognition(Intent intent) {
String photo_path = null;
// 获取选中图片的路径
String[] proj = { MediaStore.Images.Media.DATA };
Cursor cursor = getContentResolver().query(intent.getData(), proj, null, null, null);
if (cursor.moveToFirst()) {
photo_path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));
if (photo_path == null) {
photo_path = Utils.getPath(getApplicationContext(), intent.getData());
}
}
cursor.close();
QRDecode.decodeQR(photo_path, this);
} /**
* 解析二维码图片
*
* @param picturePath
* @param listener
* @return
*/
public static void decodeQR(String picturePath, OnScannerCompletionListener listener) {
try {
decodeQR(loadBitmap(picturePath), listener);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
} public static Bitmap loadBitmap(String picturePath) throws FileNotFoundException {
BitmapFactory.Options opt = new BitmapFactory.Options();
opt.inJustDecodeBounds = true;
Bitmap bitmap = BitmapFactory.decodeFile(picturePath, opt);
// 获取到这个图片的原始宽度和高度
int picWidth = opt.outWidth;
int picHeight = opt.outHeight;
// 获取画布中间方框的宽度和高度
int screenWidth = CameraManager.MAX_FRAME_WIDTH;
int screenHeight = CameraManager.MAX_FRAME_HEIGHT;
// isSampleSize是表示对图片的缩放程度,比如值为2图片的宽度和高度都变为以前的1/2
opt.inSampleSize = 1;
// 根据屏的大小和图片大小计算出缩放比例
if (picWidth > picHeight) {
if (picWidth > screenWidth)
opt.inSampleSize = picWidth / screenWidth;
} else {
if (picHeight > screenHeight)
opt.inSampleSize = picHeight / screenHeight;
}
// 生成有像素经过缩放了的bitmap
opt.inJustDecodeBounds = false;
bitmap = BitmapFactory.decodeFile(picturePath, opt);
if (bitmap == null) {
throw new FileNotFoundException("Couldn't open " + picturePath);
}
return bitmap;
}

第二种方案代码(推荐)

代码来源博客:【Android】通过Uri获取Bitmap对象

/**
* 读取一个缩放后的图片,限定图片大小,避免OOM
* http://blog.sina.com.cn/s/blog_5de73d0b0100zfm8.html
* @param uri 图片uri,支持“file://”、“content://”
* @param maxWidth 最大允许宽度
* @param maxHeight 最大允许高度
* @return 返回一个缩放后的Bitmap,失败则返回null
*/
public static Bitmap decodeUri(Context context, Uri uri, int maxWidth, int maxHeight) {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true; //只读取图片尺寸
resolveUri(context, uri, options); //计算实际缩放比例
int scale = 1;
for (int i = 0; i < Integer.MAX_VALUE; i++) {
if ((options.outWidth / scale > maxWidth &&
options.outWidth / scale > maxWidth * 1.4) ||
(options.outHeight / scale > maxHeight &&
options.outHeight / scale > maxHeight * 1.4)) {
scale++;
} else {
break;
}
} options.inSampleSize = scale;
options.inJustDecodeBounds = false;//读取图片内容
options.inPreferredConfig = Bitmap.Config.RGB_565; //根据情况进行修改
Bitmap bitmap = null;
try {
bitmap = resolveUriForBitmap(context, uri, options);
} catch (Throwable e) {
e.printStackTrace();
}
return bitmap;
} // http://blog.sina.com.cn/s/blog_5de73d0b0100zfm8.html
private static void resolveUri(Context context, Uri uri, BitmapFactory.Options options) {
if (uri == null) {
return;
} String scheme = uri.getScheme();
if (ContentResolver.SCHEME_CONTENT.equals(scheme) ||
ContentResolver.SCHEME_FILE.equals(scheme)) {
InputStream stream = null;
try {
stream = context.getContentResolver().openInputStream(uri);
BitmapFactory.decodeStream(stream, null, options);
} catch (Exception e) {
Log.w("resolveUri", "Unable to open content: " + uri, e);
} finally {
if (stream != null) {
try {
stream.close();
} catch (IOException e) {
Log.w("resolveUri", "Unable to close content: " + uri, e);
}
}
}
} else if (ContentResolver.SCHEME_ANDROID_RESOURCE.equals(scheme)) {
Log.w("resolveUri", "Unable to close content: " + uri);
} else {
Log.w("resolveUri", "Unable to close content: " + uri);
}
} // http://blog.sina.com.cn/s/blog_5de73d0b0100zfm8.html
private static Bitmap resolveUriForBitmap(Context context, Uri uri, BitmapFactory.Options options) {
if (uri == null) {
return null;
} Bitmap bitmap = null;
String scheme = uri.getScheme();
if (ContentResolver.SCHEME_CONTENT.equals(scheme) ||
ContentResolver.SCHEME_FILE.equals(scheme)) {
InputStream stream = null;
try {
stream = context.getContentResolver().openInputStream(uri);
bitmap = BitmapFactory.decodeStream(stream, null, options);
} catch (Exception e) {
Log.w("resolveUriForBitmap", "Unable to open content: " + uri, e);
} finally {
if (stream != null) {
try {
stream.close();
} catch (IOException e) {
Log.w("resolveUriForBitmap", "Unable to close content: " + uri, e);
}
}
}
} else if (ContentResolver.SCHEME_ANDROID_RESOURCE.equals(scheme)) {
Log.w("resolveUriForBitmap", "Unable to close content: " + uri);
} else {
Log.w("resolveUriForBitmap", "Unable to close content: " + uri);
} return bitmap;
}

如何用zxing解析Bitmap

/**
* 解析二维码图片
*
* @param srcBitmap
* @return
*/
public static com.google.zxing.Result decodeQR(Bitmap srcBitmap) {
com.google.zxing.Result result = null;
if (srcBitmap != null) {
int width = srcBitmap.getWidth();
int height = srcBitmap.getHeight();
int[] pixels = new int[width * height];
srcBitmap.getPixels(pixels, 0, width, 0, 0, width, height);
// 新建一个RGBLuminanceSource对象
RGBLuminanceSource source = new RGBLuminanceSource(width, height, pixels);
// 将图片转换成二进制图片
BinaryBitmap binaryBitmap = new BinaryBitmap(new GlobalHistogramBinarizer(source));
QRCodeReader reader = new QRCodeReader();// 初始化解析对象
try {
result = reader.decode(binaryBitmap, CodeHints.getDefaultDecodeHints());// 开始解析
} catch (NotFoundException e) {
e.printStackTrace();
} catch (ChecksumException e) {
e.printStackTrace();
} catch (FormatException e) {
e.printStackTrace();
}
}
return result;
}

其中CodeHints是一个自定义类,类代码:

import java.util.ArrayList;
import java.util.EnumMap;
import java.util.List;
import java.util.Map; import com.google.zxing.BarcodeFormat;
import com.google.zxing.DecodeHintType;
import com.google.zxing.EncodeHintType;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel; import android.text.TextUtils; public class CodeHints {
private static Map<DecodeHintType, Object> DECODE_HINTS = new EnumMap<DecodeHintType, Object>(DecodeHintType.class);
private static Map<EncodeHintType, Object> ENCODE_HINTS = new EnumMap<>(EncodeHintType.class); static {
List<BarcodeFormat> formats = new ArrayList<BarcodeFormat>();
formats.add(BarcodeFormat.QR_CODE);
DECODE_HINTS.put(DecodeHintType.POSSIBLE_FORMATS, formats);
// DECODE_HINTS.put(DecodeHintType.CHARACTER_SET, "UTF-8"); ENCODE_HINTS.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L);
// ENCODE_HINTS.put(EncodeHintType.CHARACTER_SET, "UTF-8");
} /**
* 获取默认解析QR参数
*
* @return
*/
public static Map<DecodeHintType, Object> getDefaultDecodeHints() {
return DECODE_HINTS;
} /**
* 获取自定义解析QR参数
*
* @param characterSet
* 编码方式
* @return
*/
public static Map<DecodeHintType, Object> getCustomDecodeHints(String characterSet) {
Map<DecodeHintType, Object> decodeHints = new EnumMap<DecodeHintType, Object>(DecodeHintType.class);
List<BarcodeFormat> formats = new ArrayList<BarcodeFormat>();
formats.add(BarcodeFormat.QR_CODE);
// 设置解码格式
decodeHints.put(DecodeHintType.POSSIBLE_FORMATS, formats);
// 设置编码方式
if (TextUtils.isEmpty(characterSet)) {
characterSet = "UTF-8";
}
decodeHints.put(DecodeHintType.CHARACTER_SET, characterSet);
return decodeHints;
} /**
* 获取默认生成QR参数
*
* @return
*/
public static Map<EncodeHintType, Object> getDefaultEncodeHints() {
return ENCODE_HINTS;
} /**
* 获取自定义生成QR参数
*
* @param level
* 容错率 L,M,Q,H
* @param version
* 版本号 1-40
* @param characterSet
* 编码方式
* @return
*/
public static Map<EncodeHintType, Object> getCustomEncodeHints(ErrorCorrectionLevel level, Integer version,
String characterSet) {
Map<EncodeHintType, Object> encodeHints = new EnumMap<>(EncodeHintType.class);
// 设置容错率
if (level != null) {
encodeHints.put(EncodeHintType.ERROR_CORRECTION, level);
}
// 设置版本号
if (version >= 1 && version <= 40) {
encodeHints.put(EncodeHintType.QR_VERSION, version);
}
// 设置编码方式
if (!TextUtils.isEmpty(characterSet)) {
// characterSet = "UTF-8";
encodeHints.put(EncodeHintType.CHARACTER_SET, characterSet);
}
return encodeHints;
} }

Android从本地选择图片文件转为Bitmap,并用zxing解析Bitmap的更多相关文章

  1. 用java开发图形界面项目,如何实现从本地选择图片文件并以二进制流的形式保存到MySQL数据库,并重新现实到面板

  2. type="file"实现兼容IE8本地选择图片预览

    一.HTML代码 <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Uploa ...

  3. JS将图片文件转为64位字符串再post到接口上传图片

    HTML: <div class="ai-item upload-id-img"> <p>上传身份证照片</p> <div class=& ...

  4. vue使用readAsDataURL实现选择图片文件后预览

    vue实现选择图片文件后预览 利用h5的api可以实现选择文件并实现预览 readAsDataURL 方法会读取指定的 Blob 或 File 对象.读取操作完成的时候,readyState 会变成已 ...

  5. Android 调用图库选择图片实现和参数详解

    //选择图片,调用图库        bt4.setOnClickListener(new OnClickListener() { @Override            public void o ...

  6. [Android] 针对生成的图片文件在系统Gallery不显示的处理

    之前遇到过一个问题,就是发现我在程序中生成一个新的 Bitmap 之后,当我打开系统的 Gallery 查看时,并没有看到新生成的图像.然而打开文件浏览器,找到保存 Bitmap 所在的文件夹下,还能 ...

  7. Android获取本地相册图片、拍照获取图片

    需求:从本地相册找图片,或通过调用系统相机拍照得到图片. 容易出错的地方: 1,当我们指定了照片的uri路径,我们就不能通过data.getData();来获取uri,而应该直接拿到uri(用全局变量 ...

  8. Android中获取选择图片与获取拍照返回结果差异

    导语: 如今的安卓应用在选择图片的处理上大多合并使用拍照和从相册中选择这两种方式 今天在写一个这样的功能时遇到一个尴尬的问题,同样是拍照获取图片功能,在不同手机上运行的效果不一样,下面是在某型手机上测 ...

  9. Android lint 删除无用图片文件和配置文件

    Android lint  删除无用.冗余的  配置文件和 图片资源    转载请注明  http://blog.csdn.net/aaawqqq?viewmode=contents Android项 ...

随机推荐

  1. 数据绑定—Source(绑定到静态类的静态属性)

    <UserControl x:Class="绑定.绑定Source" xmlns="http://schemas.microsoft.com/winfx/2006/ ...

  2. cf804C(dfs染色)

    题目链接: http://codeforces.com/problemset/problem/804/C 题意: 有一颗含有 n 个顶点的树, 第 i 个顶点上有 k 个冰激凌, 每个冰激凌的种类为 ...

  3. HyperLedger Explore 浏览器配置启动教程

    Hyperledger Fabric维护的实际上是一个区块链网络.为了能够直观的观察网络上的节点,交易等行为,Hyperledger Explore随之诞生. 本文讲述如何搭建 Hyperledger ...

  4. 前后分离调用API跨域

    前后分离调用API接口跨域问题 什么是跨域?  跨域是指一个域下的文档或脚本试图去请求另一个域下的资源,这里跨域是广义的. 广义的跨域: 资源跳转:A链接.重定向.表单提交. 资源嵌入: <li ...

  5. Python 软件热更新

    Python 软件热更新 本篇文章涉及技术知识如下: Redis threading 多线程 PyQt5 importlib 热更新 场景 咱们在平时运行一些长时间都会一直运行的软件(如:某些云同步软 ...

  6. js中去掉字符中间空格和首尾空格

    转载: https://www.jb51.net/article/109522.htm 1.  去掉字符串前后所有空格: 代码如下: ? 1 2 3 4 function Trim(str)  {   ...

  7. spring框架详细课程视频

    https://ke.qq.com/course/27346#term_id=100012852

  8. java编程如何实现2017-01-16 22:28:26.0这样的时间数据,转换成2017:01:16:22:28:26这样的时间数据

    不多说,直接上干货! timereplace.java package zhouls.bigdata.DataFeatureSelection.util; /* * 这个程序,是用来做补充的 */ p ...

  9. Storm概念学习系列之Storm与Hadoop的角色和组件比较

    不多说,直接上干货! Storm与Hadoop的角色和组件比较 Storm 集群和 Hadoop 集群表面上看很类似.但是 Hadoop 上运行的是 MapReduce 作业,而在 Storm 上运行 ...

  10. 你一直在用的 Spring Boot Starters 究竟是怎么回事

    Spring Boot 对比 Spring MVC 最大的优点就是使用简单,约定大于配置.不会像之前用 Spring MVC 的时候,时不时被 xml 配置文件搞的晕头转向,冷不防还因为 xml 配置 ...