需求:用户上传二维码识别图中的二维码
复制代码
1.maven中添加依赖
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
<version>3.3.0</version>
</dependency>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>javase</artifactId>
<version>3.3.0</version>
</dependency>
复制代码
2.创建工具类
public class QrcodeUtils {
private QrcodeUtils() {
}
/**
* 解析指定路径下的二维码图片
*
* @param filePath 二维码图片路径
* @return
*/
public static String parseQRCode(String filePath) {
String content = "";
try {
File file = new File(filePath);
BufferedImage image = ImageIO.read(file);
LuminanceSource source = new BufferedImageLuminanceSource(image);
Binarizer binarizer = new HybridBinarizer(source);
BinaryBitmap binaryBitmap = new BinaryBitmap(binarizer);
Map<DecodeHintType, Object> hints = new HashMap<>();
hints.put(DecodeHintType.CHARACTER_SET, "UTF-8");
MultiFormatReader formatReader = new MultiFormatReader();
Result result = formatReader.decode(binaryBitmap, hints);
System.out.println("result 为:" + result.toString());
System.out.println("resultFormat 为:" + result.getBarcodeFormat());
System.out.println("resultText 为:" + result.getText());
//设置返回值
content = result.getText();
} catch (Exception e) {
e.printStackTrace();
}
return content;
}
/**
* 解析指定路径下的二维码图片
*
* @return
*/
public static String parseQRCode(InputStream inputStream) {
String content = "";
try {
BufferedImage image = ImageIO.read(inputStream);
LuminanceSource source = new BufferedImageLuminanceSource(image);
Binarizer binarizer = new HybridBinarizer(source);
BinaryBitmap binaryBitmap = new BinaryBitmap(binarizer);
Map<DecodeHintType, Object> hints = new HashMap<>();
hints.put(DecodeHintType.CHARACTER_SET, "UTF-8");
// hints.put(DecodeHintType.TRY_HARDER, Boolean.TRUE);
// hints.put(DecodeHintType.PURE_BARCODE, Boolean.TRUE);
MultiFormatReader formatReader = new MultiFormatReader();
Result result = formatReader.decode(binaryBitmap, hints);
System.out.println("result 为:" + result.toString());
System.out.println("resultFormat 为:" + result.getBarcodeFormat());
System.out.println("resultText 为:" + result.getText());
//设置返回值
content = result.getText();
} catch (Exception e) {
e.printStackTrace();
}
return content;
}
/**
* 解析指定路径下的二维码图片
*
* @return
*/
public static String parseQRCode(BufferedImage image) {
Map<DecodeHintType, Object> hints = new HashMap<>();
hints.put(DecodeHintType.CHARACTER_SET, "UTF-8");
String result = parseQRCode(image,hints);
if(!StringUtil.isEmpty(result)){
return result;
}
//添加HARD模式
hints.put(DecodeHintType.TRY_HARDER, Boolean.TRUE);
result = parseQRCode(image,hints);
if(!StringUtil.isEmpty(result)){
return result;
}
//无视LOGO
hints.put(DecodeHintType.PURE_BARCODE, Boolean.TRUE);
result = parseQRCode(image,hints);
if(!StringUtil.isEmpty(result)){
return result;
}
return null;
}
/**
* 解析指定路径下的二维码图片
*
* @return
*/
public static String parseQRCode(BufferedImage image,Map<DecodeHintType, Object > hints) {
String content = "";
try {
LuminanceSource source = new BufferedImageLuminanceSource(image);
Binarizer binarizer = new HybridBinarizer(source);
BinaryBitmap binaryBitmap = new BinaryBitmap(binarizer);
MultiFormatReader formatReader = new MultiFormatReader();
Result result = formatReader.decode(binaryBitmap, hints);
System.out.println("result 为:" + result.toString());
System.out.println("resultFormat 为:" + result.getBarcodeFormat());
System.out.println("resultText 为:" + result.getText());
//设置返回值
content = result.getText();
} catch (Exception e) {
e.printStackTrace();
}
return content;
}
/**
* 解析二维码(QRCode)
*
* @param input 输入流
* @return
* @throws IOException
*/
public static String decoderQRCode(InputStream input) throws IOException {
BufferedImage bufImg = null;
String content = null;
bufImg = ImageIO.read(input);
QRCodeDecoder decoder = new QRCodeDecoder();
content = new String(decoder.decode(new QRCoderImage(bufImg)), "utf-8");
return content;
}
static class QRCoderImage implements QRCodeImage {
BufferedImage bufImg;
public QRCoderImage(BufferedImage bufImg) {
this.bufImg = bufImg;
}
@Override
public int getHeight() {
return bufImg.getHeight();
}
@Override
public int getPixel(int x, int y) {
return bufImg.getRGB(x, y);
}
@Override
public int getWidth() {
return bufImg.getWidth();
}
}
/**
* 生成二维码
*
* @param url
* @return
*/
public static String generateQRCode(String url, int width, int height) {
String qr_code = Base64.getEncoder().encodeToString(
QRCode.from(url).withSize(200, 200).to(ImageType.PNG).stream()
.toByteArray());
return qr_code;
}
}
复制代码
3.调用工具类
//返回qrCode二维码内容
String qrCode = QrcodeUtils.parseQRCode(file.getInputStream());
//发现有部分二维码无法进行识别尝试对 file.getInputStream() 进行彩色转黑白
/**
* * 转换图片 * *
* 彩色转黑白
*/
public static BufferedImage changeImg(InputStream img) {
try {
Image image = ImageIO.read(img);
int srcH = image.getHeight(null);
int srcW = image.getWidth(null);
BufferedImage bufferedImage = new BufferedImage(srcW, srcH,BufferedImage.TYPE_3BYTE_BGR);
bufferedImage.getGraphics().drawImage(image, 0,0, srcW, srcH, null);
bufferedImage=new ColorConvertOp(ColorSpace.getInstance(ColorSpace.CS_GRAY),null).filter (bufferedImage,null);
return bufferedImage;
} catch (IOException e) {
e.printStackTrace();
throw new IllegalStateException("图片转换出错!", e);
}
}
复制代码
4.切图进行解析
//遇到任有部分二维码无法解析的情况
//对图片进行截取二维码所在区域,截取后再进行黑白转换二维码识别,可以识别出大多数二维码
/**
* 根据比例截图
* @param bi
* @param scaleX
* @param scaleY
* @param scaleWidth
* @param scaleHeight
* @return
*/
public final static BufferedImage cut(BufferedImage bi,Float scaleX,Float scaleY , Float scaleWidth, Float scaleHeight) {
// 读取源图像
if(bi == null){
return null;
}
try {
int srcWidth = bi.getWidth(); // 源图宽度
int srcHeight = bi.getHeight(); // 源图高度
int x = Math.round(srcWidth * scaleX);
int y = Math.round(srcHeight * scaleY);
int width = Math.round(srcWidth * scaleWidth);
int height = Math.round(srcHeight * scaleHeight);
return doCut(bi,x,y,width,height);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
private static BufferedImage doCut(BufferedImage bi,int x,int y,int width,int height){
BufferedImage tag = null;
int srcWidth = bi.getWidth(); // 源图宽度
int srcHeight = bi.getHeight(); // 源图高度
if (srcWidth > 0 && srcHeight > 0) {
Image image = bi.getScaledInstance(srcWidth, srcHeight,
Image.SCALE_DEFAULT);
// 四个参数分别为图像起点坐标和宽高
// 即: CropImageFilter(int x,int y,int width,int height)
ImageFilter cropFilter = new CropImageFilter(x, y, width, height);
Image img = Toolkit.getDefaultToolkit().createImage(
new FilteredImageSource(image.getSource(),
cropFilter));
tag = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics g = tag.getGraphics();
g.drawImage(img, 0, 0, width, height, null); // 绘制切割后的图
// g.dispose();
// 输出为文件
// try {
// ImageIO.write(tag, "JPEG", new File("/Users/test/Desktop/test.jpg"));
// } catch (IOException e) {
// e.printStackTrace();
// }
}
return tag;
}
复制代码