二维码的生成与解析-Java代码(zxing方式)
突然 就想试试二维码,然后在网上找了好久,终于让我找到了。并且生成了这个二维码:
有两种方法可以产生二维码:
(1). QRCode
QRCode应该和zxing差不多,但是我只找到了生成二维码的jar包, 没有解析二维码的jar包的资源,所以我就放弃了它。
(2). zxing
zxing相关的jar包的获取途径:点击此处
在导入了 core-3.4.0 和 javase-3.4.0之后,再使用以下的Java代码(该代码是从 这里 参考的):
import com.google.zxing.*;
import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.HybridBinarizer;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.HashMap;
import java.util.Map;
/**
* @author amorjoo.ncu
* @description 生成、解析二维码的代码 ZXing方式(https://www.jianshu.com/p/6015822d44c7)
* @version 1.8
* @date 2019/10/10 16:22
*/
public class QRCodeService {
private static final String CHARSET = "UTF-8";
private QRCodeService() {}
public static QRCodeService instance = new QRCodeService();
/**
* 生成普通的二维码
* @param contents 二维码中储存的信息
* @param width 生成二维码的宽度
* @param height 生成二维码的高度
* @param qrFile 目标文件
* @return 返回生成的二维码 - "png"格式
*/
public File encode(String contents, int width, int height, File qrFile) {
// 生成条形码时的一些配置
Map<EncodeHintType, Object> hints = new HashMap<>();
// 指定纠错等级,纠错级别(L 7%、M 15%、Q 25%、H 30%)等级越高,纠错率越高,但存储的信息越少
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M);
// 指定内容所使用字符集编码
hints.put(EncodeHintType.CHARACTER_SET, CHARSET);
//设置一下边距,默认是5
hints.put(EncodeHintType.MARGIN, 2);
BitMatrix bitMatrix;
try {
OutputStream out = new FileOutputStream(qrFile);
// 生成二维码
bitMatrix = new MultiFormatWriter().encode(contents, BarcodeFormat.QR_CODE, width, height, hints);
// 二维码的格式 - png
MatrixToImageWriter.writeToStream(bitMatrix, "png", out);
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
return qrFile;
}
/**
* 将普通二维码变成带logo的二维码
* @param qrFile 普通二维码
* @param logoFile logo的图片
* @param newQrFile 目标文件
* @return 返回带logo的二维码 - "png"格式
*/
public File encodeWithLogo(File qrFile, File logoFile, File newQrFile) {
OutputStream os = null ;
try {
Image image = ImageIO.read(qrFile) ;
int width = image.getWidth(null) ;
int height = image.getHeight(null) ;
BufferedImage bufferImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB) ;
// BufferedImage bufferImage =ImageIO.read(image) ;
Graphics2D g2 = bufferImage.createGraphics();
g2.drawImage(image, 0, 0, width, height, null) ;
int matrixWidth = bufferImage.getWidth();
int matrixHeight = bufferImage.getHeight();
// 读取Logo图片
BufferedImage logo = ImageIO.read(logoFile);
// 开始绘制图片
g2.drawImage(logo,matrixWidth / 5 * 2,matrixHeight / 5 * 2,
matrixWidth / 5, matrixHeight / 5, null);//绘制
BasicStroke stroke = new BasicStroke(5,BasicStroke.CAP_ROUND,BasicStroke.JOIN_ROUND);
g2.setStroke(stroke);// 设置笔画对象
// 指定弧度的圆角矩形
RoundRectangle2D.Float round = new RoundRectangle2D.Float((float) matrixWidth / 5 * 2,
(float) matrixHeight / 5 * 2,(float) matrixWidth / 5,
(float) matrixHeight / 5,20,20);
g2.setColor(Color.white);
g2.draw(round);// 绘制圆弧矩形
// 设置logo 有一道灰色边框
BasicStroke stroke2 = new BasicStroke(1,BasicStroke.CAP_ROUND,BasicStroke.JOIN_ROUND);
g2.setStroke(stroke2);// 设置笔画对象
RoundRectangle2D.Float round2 = new RoundRectangle2D.Float((float) matrixWidth / 5 * 2 + 2,
(float) matrixHeight / 5 * 2 + 2,(float) matrixWidth / 5 - 4,
(float) matrixHeight / 5 - 4,20,20);
g2.setColor(new Color(128,128,128));
g2.draw(round2);// 绘制圆弧矩形
g2.dispose();
bufferImage.flush() ;
os = new FileOutputStream(newQrFile) ;
JPEGImageEncoder en = JPEGCodec.createJPEGEncoder(os) ;
en.encode(bufferImage) ;
} catch (Exception e) {
e.printStackTrace();
} finally {
if(os != null) {
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return newQrFile ;
}
/**
* 解析二维码(ZXing)
* @param qrFile 二维码文件
* @return 返回解析出的字符串,若为null,则文件不存在
*/
public String decode(File qrFile) {
BufferedImage image = null;
Result result = null;
try {
image = ImageIO.read(qrFile);
if (image == null) {
System.out.println("the decode image may be not exit.");
return null;
}
LuminanceSource source = new BufferedImageLuminanceSource(image);
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
Map<DecodeHintType, Object> hints = new HashMap<>();
hints.put(DecodeHintType.CHARACTER_SET, CHARSET);
result = new MultiFormatReader().decode(bitmap, hints);
return result.getText();
} catch (Exception e) {
e.printStackTrace();
}
assert result != null;
return result.getText() ;
}
}
再让我们测试一下:
import java.io.File;
/**
* @author amorjoo.ncu
* @description //TODO
* @version 1.8
* @date 2019/10/10 17:06
*/
public class Test_QRCode {
public static void main(String[] args) {
//test_Encode_1();
test_Encode_2();
}
public static void test_Encode_1() {
File file = new File("C:\\WebProjects\\September_19\\MyWeb_1\\src\\images\\QRCode.png");
if(file.exists()) {
System.out.println(file);
file = QRCodeService.instance.encode("http://www.baidu.com",500,500,file);
System.out.println(file != null ? "操作成功!" : "操作失败!");
}else {
System.out.println("文件不存在!");
}
}
public static void test_Encode_2() {
File oldFile = new File("C:\\WebProjects\\September_19\\MyWeb_1\\src\\images\\QRCode.png");
File logo = new File("C:\\WebProjects\\September_19\\MyWeb_1\\src\\images\\yasuo.png");
File newFile = new File("C:\\WebProjects\\September_19\\MyWeb_1\\src\\images\\new.png");
if(oldFile.exists()) {
oldFile = QRCodeService.instance.encode("壮士E去不复返!",1000,1000,oldFile);
newFile = QRCodeService.instance.encodeWithLogo(oldFile, logo, newFile);
System.out.println(newFile != null ? "快乐成功!" : "快乐失败!");
}else {
System.out.println("文件不存在!");
}
}
}
运行代码之后你就会发现,图片变成了二维码。
另外,我试了一下,用其他类型的文件作为方法中的参数,好像不能成功,所以,最好参数里使用相同格式的文件(不排除偶然性)。
如果你是一个懒癌晚期患者,也可以戳 --------这里-------- 百度网盘提取码:2168 来获得jar包和java代码。
希望这篇文章能对你有帮助!