二维码
转载请注明出处:https://blog.csdn.net/u013173247/article/details/81748481
二维码又称二维条码,常见的二维码为QR Code,QR全称Quick Response,是一个近几年来移动设备上超流行的一种编码方式,它比传统的Bar Code条形码能存更多的信息,也能表示更多的数据类型。
上面都是百度百科复制的,知道咱们生成的是矩阵二维码就行。
本文是maven工程使用zxing 3.3.0的版本生成可自定义图片的二维码,并且可以去除二维码白边。(生成二维码有白边,或二维码内容多少改变有白边的同学请看这里)。
maven引入jar:
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
<version>3.3.0</version>
</dependency>
如果不是maven工程,可以直接下载 jar包下载
准备工作做完了,开始正文。
package com.neusoft.saas.contactcentre.controller.qrCode;
import java.io.File;
import java.io.IOException;
import java.util.Date;
import java.util.Hashtable;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
public class QRCodeFactory {
public static String EncodeQRCODE(String contents, int width, int height,
String iconImagePath, String codePath,String ImageName)
throws IOException, WriterException{
try{
if(width == 0){
width = 300; // 二维码图片宽度430
}
if(height == 0){
height = 300; // 二维码图片高度430
}
File testFile = new File(codePath);
if(!testFile .exists()){
testFile.mkdir();//创建目录
}
testFile = new File(codePath,ImageName);
if(!testFile .exists()){
testFile.createNewFile();//创建文件
}
String format = "png";// 二维码的图片格式png
Hashtable<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>();
// 指定纠错等级,纠错级别(L 7%、M 15%、Q 25%、H 30%)
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
// 内容所使用字符集编码
hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
// hints.put(EncodeHintType.MAX_SIZE, 350);//设置图片的最大值
// hints.put(EncodeHintType.MIN_SIZE, 200);//设置图片的最小值
hints.put(EncodeHintType.MARGIN, 0); //设置白边
BitMatrix bitMatrix = new MultiFormatWriter().encode(contents,//要编码的内容
//编码类型,目前zxing支持:Aztec 2D,CODABAR 1D format,Code 39 1D,Code 93 1D ,Code 128 1D,
//Data Matrix 2D , EAN-8 1D,EAN-13 1D,ITF (Interleaved Two of Five) 1D,
//MaxiCode 2D barcode,PDF417,QR Code 2D,RSS 14,RSS EXPANDED,UPC-A 1D,UPC-E 1D,UPC/EAN extension,UPC_EAN_EXTENSION
BarcodeFormat.QR_CODE,
width, //条形码的宽度
height, //条形码的高度
hints);//生成条形码时的一些配置,此项可选
// 生成二维码
MatrixToImageWriter.writeToFile(bitMatrix, format, testFile,iconImagePath);
return codePath+ImageName;
} catch (IOException e) {
System.err.println("图片读取异常 : "+e.getMessage());
} catch (WriterException e) {
System.err.println("图片输出异常 :"+e.getMessage());
}
return null;
}
public static void main(String[] args) throws Exception {
try {
String contents = "https://blog.csdn.net/u013173247/article/details/41676495";
String codeIconPath = "src/main/resources/view/src/static/images/QRCodeIconImg.png";
String codePath = System.getProperty("user.dir")+"/testQrcode/";
String pngStr = new Date().getTime()+".png";
String qrcodeImagePath = codePath + pngStr;
EncodeQRCODE(contents,280, 280, codeIconPath, codePath,pngStr);
if(qrcodeImagePath != null){
File file = new File(qrcodeImagePath);
String base64 = ImageUtil.encodeImgageToBase64(file);
base64 = base64.replaceAll("\r|\n", "");
// if (!file.exists()) {
// System.out.println("删除文件失败:" + qrcodeImagePath + "刚生成的file不存在!");
// } else {
// if (file.isFile()){
// file.delete();
// }
// }
System.out.println("base64");
System.out.println(base64);
}else{
System.out.println("报错了!");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
生成的二维码如下
上图二维码有很大的白边,看下源码为什么有白边。从这行开始找
BitMatrix bitMatrix = new MultiFormatWriter().encode(contents,//要编码的内容
//编码类型,目前zxing支持:Aztec 2D,CODABAR 1D format,Code 39 1D,Code 93 1D ,Code 128 1D,
//Data Matrix 2D , EAN-8 1D,EAN-13 1D,ITF (Interleaved Two of Five) 1D,
//MaxiCode 2D barcode,PDF417,QR Code 2D,RSS 14,RSS EXPANDED,UPC-A 1D,UPC-E 1D,UPC/EAN extension,UPC_EAN_EXTENSION
BarcodeFormat.QR_CODE,
width, //条形码的宽度
height, //条形码的高度
hints);//生成条形码时的一些配置,此项可选
往里跳
case QR_CODE:
writer = new QRCodeWriter();
break;
case CODE_39:
writer = new Code39Writer();
break;
case CODE_93:
writer = new Code93Writer();
break;
case CODE_128:
writer = new Code128Writer();
break;
case ITF:
writer = new ITFWriter();
break;
case PDF_417:
writer = new PDF417Writer();
break;
case CODABAR:
writer = new CodaBarWriter();
break;
case DATA_MATRIX:
writer = new DataMatrixWriter();
break;
case AZTEC:
writer = new AztecWriter();
break;
default:
throw new IllegalArgumentException("No encoder available for format " + format);
}
return writer.encode(contents, format, width, height, hints);
writer.encode(contents, format, width, height, hints)继续往里找
ErrorCorrectionLevel errorCorrectionLevel = ErrorCorrectionLevel.L;
int quietZone = QUIET_ZONE_SIZE;
if (hints != null) {
if (hints.containsKey(EncodeHintType.ERROR_CORRECTION)) {
errorCorrectionLevel = ErrorCorrectionLevel.valueOf(hints.get(EncodeHintType.ERROR_CORRECTION).toString());
}
if (hints.containsKey(EncodeHintType.MARGIN)) {
quietZone = Integer.parseInt(hints.get(EncodeHintType.MARGIN).toString());
}
}
QRCode code = Encoder.encode(contents, errorCorrectionLevel, hints);
return renderResult(code, width, height, quietZone);
QRCode code = Encoder.encode(contents, errorCorrectionLevel, hints);这行继续往里找
// Choose the mask pattern and set to "qrCode".
int dimension = version.getDimensionForVersion();
ByteMatrix matrix = new ByteMatrix(dimension, dimension);
int maskPattern = chooseMaskPattern(finalBits, ecLevel, version, matrix);
qrCode.setMaskPattern(maskPattern);
// Build the matrix and set it to "qrCode".
MatrixUtil.buildMatrix(finalBits, ecLevel, version, maskPattern, matrix);
qrCode.setMatrix(matrix);
注意!!!
int dimension = version.getDimensionForVersion();
往里找会发现
public int getDimensionForVersion() {
return 17 + 4 * versionNumber;
}
根据版本号计算出的值,本人的versionNumber值是10
dimension 值为57
main方法中要生成的是280
280/57=4余52
可以跳转生成的数据,比如此二维码可以跳转main方法中的值为228
问题来了:如果内容长度不固定,还想没有白边,怎么办?
接着往下看。
写一个去除白边的方法
public static BitMatrix deleteWhite(BitMatrix matrix){
int[] rec = matrix.getEnclosingRectangle();
int resWidth = rec[2];
int resHeight = rec[3];
BitMatrix resMatrix = new BitMatrix(resWidth, resHeight);
resMatrix.clear();
for (int i = 0; i < resWidth; i++) {
for (int j = 0; j < resHeight; j++) {
if (matrix.get(i + rec[0], j + rec[1]))
resMatrix.set(i, j);
}
}
return resMatrix;
}
在代码中调用
BitMatrix bitMatrix = new MultiFormatWriter().encode(contents,//要编码的内容
//编码类型,目前zxing支持:Aztec 2D,CODABAR 1D format,Code 39 1D,Code 93 1D ,Code 128 1D,
//Data Matrix 2D , EAN-8 1D,EAN-13 1D,ITF (Interleaved Two of Five) 1D,
//MaxiCode 2D barcode,PDF417,QR Code 2D,RSS 14,RSS EXPANDED,UPC-A 1D,UPC-E 1D,UPC/EAN extension,UPC_EAN_EXTENSION
BarcodeFormat.QR_CODE,
width, //条形码的宽度
height, //条形码的高度
hints);//生成条形码时的一些配置,此项可选
// 生成二维码
// File outputFile = new File(codePath,new Date().getTime()+".png");//指定输出路径
bitMatrix = deleteWhite(bitMatrix);
MatrixToImageWriter.writeToFile(bitMatrix, format, testFile,iconImagePath);
生成的会是没有任何白边的二维码
问题又来了:如果我就想要固定大小白边的怎么办?
修改下去除白边方法的代码
public static BitMatrix deleteWhite(BitMatrix matrix){
int[] rec = matrix.getEnclosingRectangle();
int resWidth = rec[2] + 2;
int resHeight = rec[3] + 2;
BitMatrix resMatrix = new BitMatrix(resWidth, resHeight);
resMatrix.clear();
for (int i = 0; i < resWidth; i++) {
for (int j = 0; j < resHeight; j++) {
if (matrix.get(i + rec[0], j + rec[1]))
resMatrix.set(i+1, j+1);
}
}
return resMatrix;
}
上面代码就是给二位码添加1的白边
完成。最后附上源码下载链接源码下载
转载请注明出处:https://blog.csdn.net/u013173247/article/details/81748481