二维码已经成为我们生活中,必不可少的一部分,无论支付还是社交。下面是基于Google的Zxing制作二维码照片:
什么是QR码:
1.全称是:快速响应矩阵码(94年日本发明)
2.正方形,常见是黑白色。
3.定位点:在3个角落、印有“回”字样。帮助手机快速定位。
4.容错机制:在即使没有识别全部的条码,或者说条码上面有污点同样是可以识别的。
{ 容错的系数:3%-30% },二维码照片logo实现原理。
5.存储的容量(GBK):数字是7089个、字符4296字符、中文1800。
参考库地址:https://github.com/zxing/zxing
帮助文档地址:https://github.com/zxing/zxing/wiki/Getting-Started-Developing
创建图片二维码照片:
public class WriteQrImag {
private static int WIDTH = 200;// 二维码长度和宽度
private static int HEIGTH = 200;
private static String FORMAT = "png";// 文件格式
private static int BLACK = 0xFF000000;// 用于设置图案的颜色
private static int WHITE = 0xFFFFFFFF; // 用于背景色
/**
*
* @param parameter 传入参数:照片内容、宽度、高度
* @param myhints
*/
public void writeImageMethod(HashMap<String, String> parameter, HashMap<EncodeHintType, Object> myhints) {
//初始化照片参数
HashMap<EncodeHintType, Object> hints = null;
if (myhints == null) {
hints = new HashMap<>();// 设定安装知道编码和属性值
hints.put(EncodeHintType.CHARACTER_SET, "utf-8");// 编码
// 指定纠错等级,纠错级别(L 7%、M 15%、Q 25%、H 30%)
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
hints.put(EncodeHintType.MARGIN, 1);// 设置二维码边的空度,非负数
} else {
hints = myhints;
WIDTH = Integer.parseInt(parameter.get("width"));
HEIGTH = Integer.parseInt(parameter.get("height"));
FORMAT = parameter.get("format");
BLACK = Integer.parseInt(parameter.get("black"));
WHITE = Integer.parseInt(parameter.get("white"));
}
// 使用MultiFormatWriter写出
MultiFormatWriter writer = new MultiFormatWriter();
try {
// 二维码文本内容
String text = parameter.get("text");
BitMatrix bitMatrix = writer.encode(text, BarcodeFormat.QR_CODE, WIDTH, HEIGTH, hints);
writeLogoMethod(bitMatrix, parameter);
// ZXING方法生成二维码照片
// MatrixToImageWriter.writeToPath(bitMatrix, FORMAT, file.toPath());
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* @param bitMatrix 写入的信息 自定义方法写入LOGO
* @param parameter
*/
private static void writeLogoMethod(BitMatrix bitMatrix, HashMap<String, String> parameter) {
try {
// LOGO文件地址
String fileLogo = parameter.get("fileLogo");
String fileOut = parameter.get("fileOut");
// 读取LOGO
File file = new File(fileLogo);
// 读取照片文件
BufferedImage logoImage = ImageIO.read(file);
BufferedImage qrImage = addImage(bitMatrix);
// 缩小LOGO照片
int logoW = WIDTH / 3;
int logoH = HEIGTH / 3;
Image img = logoImage.getScaledInstance(logoW, logoH, Image.SCALE_REPLICATE);
// 绘制LOGO
Graphics gs = qrImage.getGraphics();// 创建画笔
int logoX = (WIDTH - logoW) / 2;
int logoY = (HEIGTH - logoW) / 2;
gs.drawImage(img, logoX, logoY, null);
// 生成LOGO+二维码照片
ImageIO.write(qrImage, FORMAT, new File(fileOut));
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* //手动绘制照片
* @param bitMatrix
* @return qrImage
*/
private static BufferedImage addImage(BitMatrix bitMatrix) {
BufferedImage qrImage = new BufferedImage(WIDTH, HEIGTH, BufferedImage.TYPE_3BYTE_BGR);
// 绘制二维码矩阵
for (int x = 0; x < WIDTH; x++) {
for (int y = 0; y < HEIGTH; y++) {
if (bitMatrix.get(x, y)) {// 判断当前坐标是否有颜色
qrImage.setRGB(x, y, BLACK);
} else {
qrImage.setRGB(x, y, WHITE);
}
}
}
return qrImage;
}
}
读取二维码照片代码
public class ReadQrImag {
public String readQrImag(String fileImag) {
String outText = null;
try {
// 1读取照片
BufferedImage img = ImageIO.read(new File(fileImag));
// 2转换为亮度数据源
LuminanceSource luminanceSource = new BufferedImageLuminanceSource(img);
// 3使用转换器把亮度数据源转为为二进制数据
Binarizer binarizer = new HybridBinarizer(luminanceSource);
// 4二进制数据转为为二进制位图
BinaryBitmap binaryBitmap = new BinaryBitmap(binarizer);
// 5读取内容
MultiFormatReader formatReader = new MultiFormatReader();
HashMap<DecodeHintType, Object> hints = new HashMap<>();
hints.put(DecodeHintType.CHARACTER_SET, "utf-8");
Result result = formatReader.decode(binaryBitmap, hints);
outText = result.getText();
} catch (Exception e) {
e.printStackTrace();
}
return outText;
}
}
测试main方法:
public class TestImage {
public static void main(String[] args) {
WriteQrImag wQi = new WriteQrImag();
HashMap<String, String> parameter = new HashMap<>();
parameter.put("text", "www.baidu.com");
parameter.put("fileLogo", "F:/logo.jpg");
parameter.put("fileOut", "F:/imag.png");
wQi.writeImageMethod(parameter, null);
ReadQrImag readImag = new ReadQrImag();
String outText = readImag.readQrImag("f:/2.png");
System.out.println(outText);
}
}