java实现识别二维码图片功能-亚博电竞手机版

本文实例为大家分享了java实现识别二维码图片功能,供大家参考,具体内容如下

所需maven依赖

com.google.zxing javase 3.2.1 com.google.zxing core 3.3.3

实现的java类

import com.google.zxing.*; import comwww.cppcns.com.google.zxing.client.j2se.bufferedimageluminancesource; import com.google.zxing.common.hybridbinarizer; import sun.misc.base64decoder; import javax.imageio.imageio; import java.awt.image.bufferedimage; import java.io.bytearrayinputstream; import java.io.file; import java.io.ioexception; import java.util.hashmap; import java.util.map; /** * 作用:二维码识别(图片) * 类名:qrcodeutils **/ public class qrcodeutils { /** * 解析二维码,此方法解析一个路径的二维码图片 * path:图片路径 */ public static string deencodebypath(string path) { string content = null; bufferedimage image; try { image = imageio.read(new file(path)); luminancesource source = new bufferedimageluminancesource(image); binarizer binarizer = new hybridbinarizer(source); binarybitmap binarybitmap = new binarybitmap(binarizer); map hints = new hashmap(); hints.put(decodehinttype.character_set, "utf-8"); result result = new multiformatreader().decode(binarybitmap, hints);//解码 system.out.println("图片中内容: "); system.out.println("content: " result.gettext()); content = result.gettext(); } catch (ioexception e) { e.printstacktrace(); } catch (notfoundexception e) { //这里判断如果识别不了带logo的图片,重新添加上一个属性 try { image = imageio.read(new file(path)); luminancesource source = new bufferedimageluminancesource(image); binarizer binarizer = new hybridbinarizer(source); binarybitmap binarybitmap = new binarybitmap(binarizer); map hints = new hashmap(); //设置编码格式 hints.put(decodehinttype.character_set, "utf-8"); //设置优化精度 hints.put(decodehinttype.try_harder, boolean.true); //设置复杂模式开启(我使用这种方式就可以识别微信的二维码了) hints.put(decodehinttype.pure_barcode,boolean.type); result result = new multiformatreader().decode(binarybitmap, hints);//解码 system.out.println("图片中内容: "); system.out.println("content: " result.gettext()); content = result.gettext(); } catch (ioexception e) { e.printstacktrace(); } catch (notfoundexception e) { e.printstacktrace(); } } return content; } }

测试

public static void main(string [] args){ deencodebypath("d:\\users/admin/desktop/erweima/timg (5).jpg");//二维码图片路径 }

输出结果:

图片中内容:

content: http://qrcode.online

如果上述不能识别的话,那么就需要对图片处理一次,然后再进行识别,这里是个调优图片的工具类。

package com.face.ele.common.utils; import javax.imageio.imageio; import java.awt.*; import java.awt.image.bufferedimage; import java.io.file; import java.io.ioexception; /** * @author weijianxing * @description: todo * @date 2020/11/26 9:28 */ public class imageoptimizationutil { // 阈值0-255 public static int yz = 150; /** * 图像二值化处理 * * @param filepath 要处理的图片路径 * @param fileoutputpath 处理后的图片输出路径 */ public static void binarization(string filepath, string fileoutputpath) throws ioexception { file file = new file(filepath); bufferedimage bi = imageio.read(file); // 获取当前图片的高,宽,argb int h = bi.getheight(); int w = bi.getwidth(); int arr[][] = new int[w][h]; // 获取图片每一像素点的灰度值 for (int i = 0; i < w; i ) { for (int j = 0; j < h; j ) { // getrgb()返回默认的rgb颜色模型(十进制) arr[i][j] = getimagegray(bi.getrgb(i, j));// 该点的灰度值 } } // 构造一个类型为预定义图像类型,bufferedimage bufferedimage bufferedimage = new bufferedimage(w, h, bufferedimage.type_byte_binary); // 和预先设置的阈值大小进行比较,大的就显示为255即白色,小的就显示为0即黑色 for (int i = 0; i < w; i ) { for (int j = 0; j < h; j ) { if (getgray(arr, i, j, w, h) > yz) { int white = new color(255, 255, 255).getrgb(); bufferedimage.setrgb(i, j, white); } else { int black = new color(0, 0, 0).getrgb(); bufferedimage.setrgb(i, j, black); } } } imageio.write(bufferedimage, "jpg", new file(fileoutputpath)); } /** * 图像的灰度处理 * 利用浮点算法:gray = r*0.3 g*0.59 b*0.11; * * @param rgb 该点的rgb值 * @return 返回处理后的灰度值 */ private static int getimagegray(int rgb) { string argb = integer.tohexstring(rgb);// 将十进制的颜色值转为十六进制 // argb分别代表透明,红,绿,蓝 分别占16进制2位 int r = integer.parseint(argb.substring(2, 4), 16);// 后面参数为使用进制 int g = integer.parseint(argb.substring(4, 6), 16); int b = integer.parseint(argb.substring(6, 8), 16); int gray = (int) (r*0.28 g*0.95 b*0.11); return gray; } /** * 自己加周围8个灰度值再除以9,算出其相对灰度值 * * @param gray * @param x 要计算灰度的点的横坐标 * @param y 要计算灰度的点的纵坐标 * @param w 图像的宽度 * @param h 图像的高度 * @return */ public static int getgray(int gray[][], int x, int y, int w, int h) { int rs = gray[x][y] (x == 0 ? 255 : gray[x - 1][y]) (x == 0 || y == 0 ? 255 : gray[x - 1][y - 1]) (x == 0 || y == h - 1 ? 255 : gray[x - 1][y 1]) (y == 0 ? 255 : gray[x][y - 1]) (y == h - 1 ? 255 : gray[x][y 1]) (x == w - 1 ? 255 : gray[x 1][y]) (x == w - 1 || y == 0 ? 255 : gray[x 1][y - 1]) (x == w - 1 || y == h - 1 ? 255 : gray[x 1][y 1]); return rs / 9; } /** * 二值化后的图像的开运算:先腐蚀再膨胀(用于去除图像的小黑点) * * @param filepath 要处理的图片路径 * @param fileoutputpath 处理后的图片输出路径 * @throws ioexception */ public static void opening(string filepath, string fileoutputpath) throws ioexception { file file = new file(filepath); bufferedimage bi = imageio.read(file); // 获取当前图片的高,宽,argb int h = bi.getheight(); int w = bi.getwidth(); int arr[][] = new int[w][h]; // 获取图片每一像素点的灰度值 for (int i = 0; i < w; i ) { for (int j = 0; j < h; j ) { // getrgb()返回默认的rgb颜色模型(十进制) arr[i][j] = getimagegray(bi.getrgb(i, j));// 该点的灰度值 } } int black = new color(0, 0, 0).getrgb(); int white = new color(255, 255, 255).getrgb(); bufferedimage bufferedimage = new bufferedimage(w, h, bufferedimage.type_byte_binary); // 临时存储腐蚀后的各个点的亮度 int temp[][] = new int[w][h]; // 1.先进行腐蚀操作 for (int i = 0; i < w; i ) { for (int j = 0; j < h; j ) { /* * 为0表示改点和周围8个点都是黑,则该点腐蚀操作后为黑 * 由于公司图片态模糊,完全达到9个点全为黑的点太少,最后效果很差,故改为了小于30 * (写30的原因是,当只有一个点为白,即总共255,调用getgray方法后得到255/9 = 28) */ if (getgray(arr, i, j, w, h) < 30) { temp[i][j] = 0; } else{ temp[i][j] = 255; } } } // 2.再进行膨胀操作 for (int i = 0; i < w; i ) { for (int j = 0; j < h; j ) { bufferedimage.setrgb(i, j, white); } } for (int i = 0; i < w; i ) { for (int j = 0; j < h; j ) { // 为0表示改点和周围8个点都是黑,则该点腐蚀操作后为黑 if (temp[i][j] == 0) { bufferedimage.setrgb(i, j, black); if(i > 0) { bufferedimage.setrgb(i-1, j, black); } if (j > 0) { bufferedimage.setrgb(i, j-1, black); } if (i > 0 && j > 0) { bufferedimage.setrgb(i-1, j-1, black); } if (j < h-1) { bufferedimage.setrgb(i, j 1, black); } if (i < w-1) { bufferedimage.setrgb(i 1, j, black); } if (i < w-1 && j > 0) { bufferedimage.setrgb(i 1, j-1, black); } if (i < w-1 && j < h-1) { bufferedimage.setrgb(i 1, j 1, black); } if (i > 0 && j < h-1) { bufferedimage.setrgb(i-1, j 1, black); } } } } imageio.write(bufferedimage, "jpg", new file(fileoutputpath)); } public static void main(string[] args) { string fullpath="e:\\weijianxing\\img\\微信图片_20201202160240.jpg"; string newpath="e:\\weijianxing\\img\\1new_微信图片_20201202160240.jpg"; try { imageoptimizationutil.binarization(fullpath,newpath); } catch (ioexception e) { e.printstacktrace(); } } }

可以手动测试,然后对改代码的部分进行调正对应的参数-- gray变量里的计算进行灰度调整

private static int getimagegray(int rgb) { string argb = integer.tohexstring(rgb);// 将十进制的颜色值转为十六进制 // argb分别代表透明,红,绿,蓝 分别占16进制2位 int r = integer.parseint(argb.substring(2, 4), 16);// 后面参数为使用进制 int g = integer.parseint(argb.substring(4, 6), 16); int b = integer.parseint(argb.substring(6, 8), 16); int gray = (int) (r*0.28 g*0.95 b*0.11); return gray; }

等调整之后,在对图片进行识别即可。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

展开全文
内容来源于互联网和用户投稿,文章中一旦含有亚博电竞手机版的联系方式务必识别真假,本站仅做信息展示不承担任何相关责任,如有侵权或涉及法律问题请联系亚博电竞手机版删除

最新文章

网站地图