2000字范文,分享全网优秀范文,学习好帮手!
2000字范文 > 使用zxing生成的二维码边框大小无法自定义问题

使用zxing生成的二维码边框大小无法自定义问题

时间:2023-07-23 11:46:54

相关推荐

使用zxing生成的二维码边框大小无法自定义问题

之前的项目用到了zxing生成二维码,发现周围的白框大的感人,使用EncodeHintType.MARGIN设置也没什么效果。今天看了一下zxing的源码,才发现其中的缘由。

先来看我原本是怎么使用zxing生成二维码的

/*** 生成二维码* @param url 二维码内容* @return 返回新image*/public static BufferedImage createQRcode(String url) throws Exception {int width = 300;int height = 300;Hashtable<EncodeHintType, Object> hints = new Hashtable<>();hints.put(EncodeHintType.CHARACTER_SET, "utf-8");hints.put(EncodeHintType.MARGIN, 0);hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);BitMatrix bitMatrix = new MultiFormatWriter().encode(url, BarcodeFormat.QR_CODE, width, height, hints);// 生成二维码BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);for (int x = 0; x < width; x++) {for (int y = 0; y < height; y++) {image.setRGB(x, y, bitMatrix.get(x, y) ? BLACK : WHITE);}}return image;}

顺着源码点下去,最后发现是在renderResult()方法里对宽高做了一系列的处理

我们发现我们设置的hints.put(EncodeHintType.MARGIN, 0)边距并没有直接使用,而是经过一系列的计算得出了 leftPadding 与 topPadding。

private static BitMatrix renderResult(AztecCode code, int width, int height) {BitMatrix input;if ((input = code.getMatrix()) == null) {throw new IllegalStateException();} else {int inputWidth = input.getWidth();int inputHeight = input.getHeight();int outputWidth = Math.max(width, inputWidth);int outputHeight = Math.max(height, inputHeight);int multiple = Math.min(outputWidth / inputWidth, outputHeight / inputHeight);int leftPadding = (outputWidth - inputWidth * multiple) / 2;int topPadding = (outputHeight - inputHeight * multiple) / 2;BitMatrix output = new BitMatrix(outputWidth, outputHeight);int inputY = 0;for(int outputY = topPadding; inputY < inputHeight; outputY += multiple) {int inputX = 0;for(int outputX = leftPadding; inputX < inputWidth; outputX += multiple) {if (input.get(inputX, inputY)) {output.setRegion(outputX, outputY, multiple, multiple);}++inputX;}++inputY;}return output;}}

inputWidth ,inputHeight 是 zxing 根据我们所传的url与指定的BarcodeFormat.QR_CODE规则生成的。

比如我们传入的宽和高为250

可以看到生成的inputWidth 和 inputHeight 为33,

quietZone就是我们之前传入的1,

width,height都是之前设置的250。

multiple=7,

内容区为33x33,而我们需要的大小为250x250,33放大7倍后为231,距离250还差19。

19/2 =9

最后经过计算得出了 leftPadding 与 topPadding 都为 9。

如果此时将margin设为 4, 宽和高还是设为 250

故multiple=6,leftPading =(250 - 33*6)/2 = 26,两边就有很大的空白。

zxing会采用这种策略,是为了提高二维码的容错率,以免出现失真导致二维码无法扫描。

了解了zxing的这种计算机制后,我们就可以根据想要的边框大小来传入相应的值了。

为了解决这种留白自定义问题,我们可以采用另外一种方式——图片缩放

/*** 生成二维码* @param url 二维码内容* @return 返回新image*/public static BufferedImage createQRcode(String url) throws Exception {//二维码容错率,分四个等级:H、L 、M、 Q//生成二维码中的设置Hashtable hints = new Hashtable();//编码、容错率、二维码边框宽度,这里文档说设置0-4hints.put(EncodeHintType.CHARACTER_SET, "utf-8");hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H); hints.put(EncodeHintType.MARGIN, 0);//二维码图片大小int size = 200; //生成bitMatrixBitMatrix bitMatrix = new MultiFormatWriter().encode(url, BarcodeFormat.QR_CODE, size, size,hints);//自定义白边边框宽度int margin = 5; //生成新的bitMatrixbitMatrix = updateBit(bitMatrix, margin); //因为二维码生成时,白边无法控制,去掉原有的白边,再添加自定义白边后,二维码大小与size大小就存在差异了,//为了让新生成的二维码大小还是size大小,根据size重新生成图片BufferedImage bi = MatrixToImageWriter.toBufferedImage(bitMatrix);//根据size放大、缩小生成的二维码bi = zoomInImage(bi,size,size);}/***因为二维码边框设置那里不起作用,不管设置多少,都会生成白边,所以根据网上*的例子进行修改,自定义控制白边宽度,该方法生成自定义白边框后的bitMatrix;*/private BitMatrix updateBit(BitMatrix matrix, int margin){int tempM = margin*2;//获取二维码图案的属性int[] rec = matrix.getEnclosingRectangle(); int resWidth = rec[2] + tempM;int resHeight = rec[3] + tempM;// 按照自定义边框生成新的BitMatrixBitMatrix resMatrix = new BitMatrix(resWidth, resHeight); resMatrix.clear();//循环,将二维码图案绘制到新的bitMatrix中for(int i= margin; i < resWidth- margin; i++){for(int j=margin; j < resHeight-margin; j++){if(matrix.get(i-margin + rec[0], j-margin + rec[1])){resMatrix.set(i,j);}}}return resMatrix;}/*** 图片放大缩小*/public static BufferedImage zoomInImage(BufferedImage originalImage, int width, int height){BufferedImage newImage = new BufferedImage(width,height,originalImage.getType());Graphics g = newImage.getGraphics();g.drawImage(originalImage, 0,0,width,height,null);g.dispose();return newImage;}

借鉴的文章地址:

/article/1280736011311136768.htm

/yjanb11/articles/11655194.html

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。