Android的二维码功能实现以及长按识别二维码
来源:互联网 发布:日本黑科技 知乎 编辑:程序博客网 时间:2024/05/21 17:09
一、初步集成zxing
二、获得Zxing的核心功能
三、实现扫描和长按读取等功能
//生成二维码图片,第一个参数是二维码的内容,第二个参数是正方形图片的边长,单位是像素 Bitmap bitmap = null;try {bitmap = BitmapUtil.createQRCode(msg, 400);} catch (WriterException e) {// TODO Auto-generated catch blocke.printStackTrace();} imageView.setImageBitmap(bitmap);
然后将生成的二维码放置到相应的位置即可。
现在微信基本上都有长按二维码识别,这种实现我的思路就是,既然二维码扫描能够识别,那么肯定也是能够解析图片的,那么我们可以长按实现对当前屏幕截屏然后调用相关的类去解析即可:
我们先看下截屏的代码,都有注释自己看吧:
//这种方法状态栏是空白,显示不了状态栏的信息 private void saveCurrentImage() { //获取当前屏幕的大小 int width = getWindow().getDecorView().getRootView().getWidth(); int height = getWindow().getDecorView().getRootView().getHeight(); //生成相同大小的图片 Bitmap temBitmap = Bitmap.createBitmap( width, height, Bitmap.Config.ARGB_8888 ); //找到当前页面的根布局 View view = getWindow().getDecorView().getRootView(); //设置缓存 view.setDrawingCacheEnabled(true); view.buildDrawingCache(); //从缓存中获取当前屏幕的图片,创建一个DrawingCache的拷贝,因为DrawingCache得到的位图在禁用后会被回收 temBitmap = view.getDrawingCache(); SimpleDateFormat df = new SimpleDateFormat("yyyymmddhhmmss"); time = df.format(new Date()); if(Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())){ file = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/screen",time + ".png"); if(!file.exists()){ file.getParentFile().mkdirs(); try { file.createNewFile(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } FileOutputStream fos = null; try { fos = new FileOutputStream(file); temBitmap.compress(Bitmap.CompressFormat.PNG, 100, fos); fos.flush(); fos.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } //禁用DrawingCahce否则会影响性能 ,而且不禁止会导致每次截图到保存的是第一次截图缓存的位图 view.setDrawingCacheEnabled(false); } }
上面将屏幕截图并以当前的时间为名字保存到手机上了,我们解析直接可以将路径传递进入解析就好了,我把相关的类传递上来,都有注释,大家看看吧:
//解析二维码图片,返回结果封装在Result对象中 private com.google.zxing.Result parseQRcodeBitmap(String bitmapPath){ //解析转换类型UTF-8 Hashtable<DecodeHintType, String> hints = new Hashtable<DecodeHintType, String>(); hints.put(DecodeHintType.CHARACTER_SET, "utf-8"); //获取到待解析的图片 BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; Bitmap bitmap = BitmapFactory.decodeFile(bitmapPath,options); options.inSampleSize = options.outHeight / 400; if(options.inSampleSize <= 0){ options.inSampleSize = 1; //防止其值小于或等于0 } options.inJustDecodeBounds = false; bitmap = BitmapFactory.decodeFile(bitmapPath, options); //新建一个RGBLuminanceSource对象,将bitmap图片传给此对象 RGBLuminanceSource rgbLuminanceSource = new RGBLuminanceSource(bitmap); //将图片转换成二进制图片 BinaryBitmap binaryBitmap = new BinaryBitmap(new HybridBinarizer(rgbLuminanceSource)); //初始化解析对象 QRCodeReader reader = new QRCodeReader(); //开始解析 Result result = null; try { result = reader.decode(binaryBitmap, hints); } catch (Exception e) { // TODO: handle exception } return result; }
按照zxing的解码规则,我们是需要一个BitmapLuminanceSource类的,也是唯一需要去实现的
BitmapLuminanceSource继承自LuminanceSource这个抽象类,需要实现它的构造方法,其构造方法中需要传入宽高,这两个值指的就是图片的宽和高。getMatrix()方法会返回一个byte数组,这个数组就是图片的像素数组。getRow(int y, byte[] row)如字面的意义,就是得到图片像素数组的一行。其中的y就是需要的哪一个行的像素数组。
以下是完整的BitmapLuminanceSource类
public class RGBLuminanceSource extends LuminanceSource {private byte bitmapPixels[]; protected RGBLuminanceSource(Bitmap bitmap) { super(bitmap.getWidth(), bitmap.getHeight()); // 首先,要取得该图片的像素数组内容 int[] data = new int[bitmap.getWidth() * bitmap.getHeight()]; this.bitmapPixels = new byte[bitmap.getWidth() * bitmap.getHeight()]; bitmap.getPixels(data, 0, getWidth(), 0, 0, getWidth(), getHeight()); // 将int数组转换为byte数组for (int i = 0; i < data.length; i++) { this.bitmapPixels[i] = (byte) data[i]; } } @Override public byte[] getMatrix() { // 返回我们生成好的像素数据 return bitmapPixels; } @Override public byte[] getRow(int y, byte[] row) { // 这里要得到指定行的像素数据 System.arraycopy(bitmapPixels, y * getWidth(), row, 0, getWidth()); return row; } }
上面获取图片像素组内容的byte[]数组是指图片的像素数组,而不是所谓的Bitmap转换成byte数组
Bitmap对象的getPixels方法可以取得的像素数组,但它得到是int型数组。根据其api文档解释,取得的是color,也就是像素颜色值。每个像素值包含透明度,红色,绿色,蓝色。所以白色就是0xffffffff,黑色就是0xff000000。直接由int型转成byte型,实现上相当于我们这里只取其蓝色值部分。
getPixels得到的像素数组是一维的,也就是按照图片宽度逐行取像素颜色值录入。如果想得到单行的像素数组内容,通过y*width就可以找该行的第一个像素值,拷贝后面width个就可以得到该行的像素内容。
最后一个就是getMatrix()方法,它用来返回我们的图像转换成的像素数组。
最后我们将长按存储的图片路径传递进去即可,但是注意解析的时候开个线程,不然要ANR,基本上实现了我们需要的大部分生成、读取、识别大部分功能。
稍后上传源码给大家,觉得有用就点个赞吧,上一次由于上传的资源的时候把imageview的大小设置成定值,导致识别不了,现在重新上传是正常的了。。。。。
源码下载猛戳 源码下载
- Android的二维码功能实现以及长按识别二维码
- 二维码的生成以及长按识别
- 长按二维码识别
- Android 基于google Zxing实现二维码的生成,识别和长按识别的效果
- 实现长按识别webview中的二维码
- Android 长按识别图中二维码
- 生成二维码,长按识别二维码
- 安卓webView实现长按二维码的自动识别功能
- 安卓webView实现长按二维码的自动识别功能
- 安卓webView实现长按二维码的自动识别功能
- android webView使用js/css实现夜间模式 长按识别图片以及二维码,网页可以上传图片
- 长按二维码不识别
- iOS之长按识别二维码/生成二维码/扫描二维码
- 重磅!微信小程序开放长按识别二维码功能
- 微信小程序点击图片实现长按预览、保存、识别带参数二维码、转发等功能
- android开发之集成zxing,二维码,以及扫描二维码的功能实现。带源代码下载
- 微信内置浏览器 长按识别二维码 功能的两三个坑与解决方案
- 微信内置浏览器 长按识别二维码 功能的两三个坑与解决方案
- lua入门系列
- 面试题59:二叉树序列化
- LINK : fatal error LNK1104: 无法打开文件“gdi32.lib”
- 爬虫 Cookie 学习
- bootstraps对于低于IE9版本的支持
- Android的二维码功能实现以及长按识别二维码
- leetcode——278—— First Bad Version
- Spring中Resource对象的获取
- 深度学习与自然语言处理学习资料
- Java day08 异常处理与正常代码分离 图形面积
- java 常见异常
- Currying & Partial[applied] function 初体验
- MongoDB MapReduce
- [BZOJ2243]染色 做题笔记