生成图片二维码 and 拍照解码图片二维码内容工具类

290 阅读4分钟

目的:

         记录可行可用方案,方便下次取用。

1、maven工程pom.xml引入

<!--  二维码 begin--> 
<dependency>
    <groupId>com.google.zxing</groupId>
    <artifactId>javase</artifactId>
    <version>3.2.1</version>
</dependency>
<dependency>
    <groupId>com.google.zxing</groupId>
    <artifactId>core</artifactId>
    <version>3.3.3</version>
</dependency>
<!-- 二维码end -->

2、工具类QRCodeUtils.java

package com.common.utils;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;

import javax.imageio.ImageIO;

import com.baidu.aip.util.Base64Util;
import com.github.binarywang.utils.qrcode.BufferedImageLuminanceSource;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.Binarizer;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.DecodeHintType;
import com.google.zxing.EncodeHintType;
import com.google.zxing.LuminanceSource;
import com.google.zxing.MultiFormatReader;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.NotFoundException;
import com.google.zxing.Result;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.HybridBinarizer;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;

import sun.misc.BASE64Decoder;

/**
 * 二维码识别(图片)
 *
 */
public class QRCodeUtils {

	private static final int BLACK = 0xFF000000;
	private static final int WHITE = 0xFFFFFFFF;
	private static final int margin = 0;
	private static final int LogoPart = 4;

	/**
	 * 解析二维码解析,此方法是解析Base64格式二维码图片 baseStr:base64字符串,data:image/png;base64开头的
	 */
	public static String deEncodeByBase64(String baseStr) {
		String content = null;
		BufferedImage image;
		BASE64Decoder decoder = new BASE64Decoder();
		byte[] b = null;
		try {
			int i = baseStr.indexOf("data:image/png;base64,");
			if (i != -1) {
				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);
			LuminanceSource source = new BufferedImageLuminanceSource(image);
			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);// 解码
			content = result.getText();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (NotFoundException e) {
			e.printStackTrace();
		}
		return content;
	}

	/**
	 * 解析二维码,此方法解析一个路径的二维码图片 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<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) {
			e.printStackTrace();
		}
		return content;
	}

	/**
	 * 生成二维码矩阵信息
	 * 
	 * @param content 二维码图片内容
	 * @param width   二维码图片宽度
	 * @param height  二维码图片高度
	 */
	public static BitMatrix setBitMatrix(String content, int width, int height) {
		Hashtable<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>();
		hints.put(EncodeHintType.CHARACTER_SET, "UTF-8"); // 指定编码方式,防止中文乱码
		hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H); // 指定纠错等级
		hints.put(EncodeHintType.MARGIN, margin); // 指定二维码四周白色区域大小
		BitMatrix bitMatrix = null;
		try {
			bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, width, height, hints);
		} catch (WriterException e) {
			e.printStackTrace();
		}
		return bitMatrix;
	}

	/**
	 * 将二维码图片输出
	 * 
	 * @param matrix    二维码矩阵信息
	 * @param format    图片格式
	 * @param outStream 输出流
	 * @param logoPath  logo图片路径
	 */
	public static void writeToFile(BitMatrix matrix, String format, OutputStream outStream, String logoPath)
			throws IOException {
		BufferedImage image = toBufferedImage(matrix);
		// 加入LOGO水印效果
		if (StringUtils.isNotBlank(logoPath)) {
			image = addLogo(image, logoPath);
		}
		ImageIO.write(image, format, outStream);
	}

	/**
	 * 生成二维码图片
	 * 
	 * @param matrix 二维码矩阵信息
	 */
	public static BufferedImage toBufferedImage(BitMatrix matrix) {
		int width = matrix.getWidth();
		int height = matrix.getHeight();
		BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR);
		for (int x = 0; x < width; x++) {
			for (int y = 0; y < height; y++) {
				image.setRGB(x, y, matrix.get(x, y) ? BLACK : WHITE);
			}
		}
		return image;
	}

	/**
	 * 在二维码图片中添加logo图片
	 * 
	 * @param image    二维码图片
	 * @param logoPath logo图片路径
	 */
	public static BufferedImage addLogo(BufferedImage image, String logoPath) throws IOException {
		Graphics2D g = image.createGraphics();
		BufferedImage logoImage = ImageIO.read(new File(logoPath));
		// 计算logo图片大小,可适应长方形图片,根据较短边生成正方形
		int width = image.getWidth() < image.getHeight() ? image.getWidth() / LogoPart : image.getHeight() / LogoPart;
		int height = width;
		// 计算logo图片放置位置
		int x = (image.getWidth() - width) / 2;
		int y = (image.getHeight() - height) / 2;
		// 在二维码图片上绘制logo图片
		g.drawImage(logoImage, x, y, width, height, null);
		// 绘制logo边框,可选
//        g.drawRoundRect(x, y, logoImage.getWidth(), logoImage.getHeight(), 10, 10);
		g.setStroke(new BasicStroke(2)); // 画笔粗细
		g.setColor(Color.WHITE); // 边框颜色
		g.drawRect(x, y, width, height); // 矩形边框
		logoImage.flush();
		g.dispose();
		return image;
	}

	/**
	 * 为图片添加文字
	 * 
	 * @param pressText   文字
	 * @param newImage    带文字的图片
	 * @param targetImage 需要添加文字的图片
	 * @param fontStyle   字体风格
	 * @param color       字体颜色
	 * @param fontSize    字体大小
	 * @param width       图片宽度
	 * @param height      图片高度
	 */
	public static void pressText(String pressText, String newImage, String targetImage, int fontStyle, Color color,
			int fontSize, int width, int height) {
		// 计算文字开始的位置
		// x开始的位置:(图片宽度-字体大小*字的个数)/2
		int startX = (width - (fontSize * pressText.length())) / 2;
		// y开始的位置:图片高度-(图片高度-图片宽度)/2
		int startY = height - (height - width) / 2 + fontSize;
		try {
			File file = new File(targetImage);
			BufferedImage src = ImageIO.read(file);
			int imageW = src.getWidth(null);
			int imageH = src.getHeight(null);
			BufferedImage image = new BufferedImage(imageW, imageH, BufferedImage.TYPE_INT_RGB);
			Graphics g = image.createGraphics();
			g.drawImage(src, 0, 0, imageW, imageH, null);
			g.setColor(color);
			g.setFont(new Font(null, fontStyle, fontSize));
			g.drawString(pressText, startX, startY);
			g.dispose();
			FileOutputStream out = new FileOutputStream(newImage);
			ImageIO.write(image, "png", out);
			out.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static void main(String[] args) {
		//TODO ---生成二维码图片--
/**		String content = "1e84fc3ea0c111eaa083002324ddfb32";
		String format = "jpg";
		int width = 100;
		int height = 100;
		BitMatrix bitMatrix = setBitMatrix(content, width, height);
		// 可通过输出流输出到页面,也可直接保存到文件
		OutputStream outStream = null;
		String path = "C:/Users/Administrator/Desktop/" + new Date().getTime() + ".png";
		try {
			outStream = new FileOutputStream(new File(path));
			writeToFile(bitMatrix, format, outStream, null);
			outStream.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
*/
		// 添加文字效果
		//int fontSize = 12; // 字体大小
		//int fontStyle = 1; // 字体风格
		//String text = "测试二维码";
		//String withTextPath = "c:/text" + new Date().getTime() + ".png";
		//pressText(text, withTextPath, path, fontStyle, Color.BLUE, fontSize, width, height);
		
		//TODO ---解码生成图片或者拍照后的图片---
		//String file_src = "C:/Users/Administrator/Desktop/1592359181441.png";
		String file_src = "C:/Users/Administrator/Desktop/1592359858.jpg";
		byte[] from;
		try {
			from = FileUtil.readFileByBytes(file_src);
			String image = Base64Util.encode(from);
			String code = deEncodeByBase64(image);
			System.out.println("code:"+code);
		} catch (IOException e) {
			e.printStackTrace();
		}
		
	}
}

3、参考资料地址:

www.cnblogs.com/pcheng/p/75…

www.csdn.net/gather_20/N…