提交 c2cb7910 authored 作者: zhoushaopan's avatar zhoushaopan

[二维码]读取二维码

上级 4ba4d669
package com.tykj.dev.device.zxing.util;
import sun.misc.BASE64Encoder;
import javax.imageio.stream.FileImageOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Base64;
/**
* DATE:2021-7-21
* Author:zsp
*/
public class Base64Util {
public static String getImageStr(String imgFile) {
InputStream inputStream = null;
byte[] data = null;
try {
inputStream = new FileInputStream(imgFile);
data = new byte[inputStream.available()];
inputStream.read(data);
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
// 加密
Base64.Encoder encoder = Base64.getEncoder();
return encoder.encodeToString(data);
}
public static byte[] getFileBytes(String path) {
ArrayList bytesList = new ArrayList();
byte[] bytes = new byte[1];
FileInputStream inStream = null;
try {
inStream = new FileInputStream(path);
while (inStream.read(bytes) > 0) {
bytesList.add(bytes[0]);
}
bytes = new byte[bytesList.size()];
for (int i = 0; i < bytes.length; i++) {
bytes[i] = (byte) bytesList.get(i);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (inStream != null) {
inStream.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
return bytes;
}
public static void byte2image(byte[] data, String path) {
if (data.length < 3 || path.equals("")) {
return;
}
try {
FileImageOutputStream imageOutput = new FileImageOutputStream(new File(path));
imageOutput.write(data, 0, data.length);
imageOutput.close();
System.out.println("Make Picture success,Please find image in " + path);
}
catch (Exception ex) {
System.out.println("Exception: " + ex);
ex.printStackTrace();
}
}
}
package com.tykj.dev.device.zxing.util;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
public class ImageUtils {
// 阈值0-255
public static int YZ = 150;
/**
* 图像二值化处理
*
* @param bi 要处理的图片路径
* @throws IOException
*/
public static BufferedImage binarization(BufferedImage bi) throws IOException {
// 获取当前图片的高,宽,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);
}
}
}
return bufferedImage;
}
/**
* 图像的灰度处理
* 利用浮点算法: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.3 + g * 0.59 + 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 bi 要处理的图片流
* @throws IOException
*/
public static BufferedImage opening(BufferedImage bi) throws IOException {
// 获取当前图片的高,宽,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);
}
}
}
}
return bufferedImage;
}
}
package com.tykj.dev.device.zxing.util;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.rendering.PDFRenderer;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* @author ldtianzhe
* @description
* @date 2021/7/21
*/
public class PdfToImageUtil {
/**
* dpi越大转换后越清晰,相对转换速度越慢
*/
private static final Integer DPI = 300;
/**
* 转换后的图片类型
*/
private static final String IMG_TYPE = "png";
/**
* PDF转图片
*
* @param fileContent PDF文件的二进制流
* @return 图片文件的二进制流
*/
public static List<byte[]> pdfToImage(byte[] fileContent) throws IOException {
List<byte[]> result = new ArrayList<>();
try (PDDocument document = PDDocument.load(fileContent)) {
PDFRenderer renderer = new PDFRenderer(document);
for (int i = 0; i < document.getNumberOfPages(); ++i) {
BufferedImage bufferedImage = renderer.renderImageWithDPI(i, DPI);
ByteArrayOutputStream out = new ByteArrayOutputStream();
ImageIO.write(bufferedImage, IMG_TYPE, out);
result.add(out.toByteArray());
}
}
return result;
}
}
package com.tykj.dev.device.zxing.util;
import com.google.zxing.*;
import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
import com.google.zxing.common.HybridBinarizer;
import com.tykj.dev.device.task.repository.TaskDao;
import com.tykj.dev.device.task.subject.domin.Task;
import com.tykj.dev.device.zxing.vo.ZxingTaskVo;
import org.springframework.beans.factory.annotation.Autowired;
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.Base64;
import java.util.HashMap;
import java.util.Map;
/**
* 解析二维码
**/
public class QRCodeUtils {
@Autowired
private TaskDao taskDao;
/**
* 解析二维码解析,此方法是解析Base64格式二维码图片
* baseStr:base64字符串,data:image/png;base64开头的
*/
public ZxingTaskVo deEncodeByBase64(String baseStr) {
String content = null;
BufferedImage image;
BASE64Decoder decoder = new BASE64Decoder();
byte[] b=null;
try {
// int i = baseStr.indexOf("data:image/png;base64,");
// baseStr = baseStr.substring(i+"data:image/png;base64,".length());//去掉base64图片的data:image/png;base64,部分才能转换为byte[]
b = decoder.decodeBuffer(baseStr);//baseStr转byte[]
ByteArrayInputStream byteArrayInputStream=new ByteArrayInputStream(b);//byte[] 转BufferedImage
image = ImageIO.read(byteArrayInputStream);
BufferedImage temp = ImageUtils.opening(ImageUtils.binarization(image));
LuminanceSource source = new BufferedImageLuminanceSource(temp);
Binarizer binarizer = new HybridBinarizer(source);
BinaryBitmap binaryBitmap = new BinaryBitmap(binarizer);
Map<DecodeHintType, Object> hints = new HashMap<DecodeHintType, Object>();
hints.put(DecodeHintType.CHARACTER_SET, "UTF-8");
Result result = new MultiFormatReader().decode(binaryBitmap, hints);//解码
//返回taskId
ZxingTaskVo zxingTaskVo = null;
if (result.getText() != null){
Task task = taskDao.findByParentTaskId(Integer.valueOf(result.getText()));
zxingTaskVo = new ZxingTaskVo(task.getParentTaskId(), task.getId());
}
return zxingTaskVo;
// System.out.println("图片中内容: ");
// System.out.println("content: " + result.getText());
// content = result.getText();
} catch (IOException e) {
e.printStackTrace();
} catch (NotFoundException e) {
e.printStackTrace();
}
return null;
}
/**
* 解析二维码,此方法解析一个字节数组的二维码图片
* path:图片路径
*/
public static String deEncodeByBtyes(byte[] bytes) {
String content = null;
BufferedImage image;
try {
ByteArrayInputStream in = new ByteArrayInputStream(bytes);
image = ImageIO.read(in);
BufferedImage temp = ImageUtils.opening(ImageUtils.binarization(image));
LuminanceSource source = new BufferedImageLuminanceSource(temp);
Binarizer binarizer = new HybridBinarizer(source);
BinaryBitmap binaryBitmap = new BinaryBitmap(binarizer);
Map<DecodeHintType, Object> hints = new HashMap<DecodeHintType, Object>();
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 {
ByteArrayInputStream in = new ByteArrayInputStream(bytes);
image = ImageIO.read(in);
BufferedImage temp = ImageUtils.opening(ImageUtils.binarization(image));
LuminanceSource source = new BufferedImageLuminanceSource(temp);
Binarizer binarizer = new HybridBinarizer(source);
BinaryBitmap binaryBitmap = new BinaryBitmap(binarizer);
Map<DecodeHintType, Object> hints = new HashMap<DecodeHintType, Object>();
//设置编码格式
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 e1) {
e1.printStackTrace();
} catch (NotFoundException e1) {
e1.printStackTrace();
}
}
return content;
}
}
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论