通常我们生成二维码需要做以下配置
Map<EncodeHintType, Object> hints = new HashMap<>(); hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);//设置容错率默认为最高 hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");// 字符编码为UTF-8 hints.put(EncodeHintType.MARGIN, 0);//二维码空白区域,最小为0也有白边,只是很小,最小是6像素左右
生成的二维码的空白区域怎么设置都是有
实测试100、1000大小的空白像素如 top:7 right:8 bottom:8 left:7 右边、底部会多一个像素
二维码生成返回的对像 BitMatrix可以直接遍历,可以把它当作一个二维数组,通过BitMatrix.get(x,y)判断是否是一个黑点,然后复制到一个新的二 维码对像即可,实例代码如下
import com.google.zxing.BarcodeFormat; import com.google.zxing.EncodeHintType; import com.google.zxing.MultiFormatWriter; import com.google.zxing.client.j2se.MatrixToImageWriter; import com.google.zxing.common.BitMatrix; import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.FileOutputStream; import java.io.OutputStream; import java.util.HashMap; import java.util.Map; /** * Created by zengrenyuan */ public class QRCodeImageTest { private static final Logger LOG = LoggerFactory.getLogger(QRCodeImageTest.class); public static void main(String[] args) { String format = "png";// 图像类型 String target = "/data/qrcode.png"; Map<EncodeHintType, Object> hints = new HashMap<>(); hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);//设置容错率默认为最高 hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");// 字符编码为UTF-8 hints.put(EncodeHintType.MARGIN, 0);//二维码空白区域,最小为0也有白边,只是很小,最小是6%左右 try (OutputStream os = new FileOutputStream(target)) { //二维码的宽 int qrCodeWidth = 1000; BitMatrix bitMatrix = new MultiFormatWriter() .encode("https://www.baidu.com", BarcodeFormat.QR_CODE, qrCodeWidth, qrCodeWidth, hints); int height = bitMatrix.getHeight(); int width = bitMatrix.getWidth(); try (OutputStream os1 = new FileOutputStream("/data/qrcode.png")) { MatrixToImageWriter.writeToStream(bitMatrix, format, os1); } boolean isFirstBlankPoint = false;//是否第一个黑点 int left = 0;//开始的宽 int top = 0;//开始的高 for (int y = 0; y < height; y++) {//从左上角开始读 if (isFirstBlankPoint) { break; } for (int x = 0; x < width; x++) { if (bitMatrix.get(x, y) && !isFirstBlankPoint) {//如果是一个黑点就会返回true isFirstBlankPoint = true; left = x; top = y; LOG.info("f x:{} y:{}", x, y); } } } int right = 0;//右边空白区域 int bottom = 0;//底部空白区域 boolean isRightLastPoint = false; for (int x = width - 1; x >= 0; x--) {//从右上角开始读 if (isRightLastPoint) { break; } for (int y = 0; y < height; y++) { if (bitMatrix.get(x, y) && !isRightLastPoint) {//如果是一个黑点就会返回true isRightLastPoint = true; right = width - x; LOG.info("e x:{} y:{} right:{}", x, y, right); break; } } } boolean isBottomLastPoint = false; for (int y = height - 1; y >= 0; y--) {//从左理角开始读 if (isBottomLastPoint) { break; } for (int x = 0; x < width; x++) { if (bitMatrix.get(x, y) && !isBottomLastPoint) { isBottomLastPoint = true; bottom = height - y; LOG.info("e x:{} y:{} bottom:{}", x, y, bottom); break; } } } LOG.info("top:{} right:{} bottom:{} left:{} ", top, right, bottom, left); //最小的空白区域一个像素 int miniPadding = 1; //原二维码大小减去上下左右的空白区域 int newWidth = qrCodeWidth - left - right + miniPadding * 2; int newHeight = qrCodeWidth - top - bottom + miniPadding * 2; BitMatrix newBitMatrix = new BitMatrix(newWidth, newHeight); //写二维码点的宽度 int pointSize = 1; for (int y = miniPadding; y < newHeight; y++) { for (int x = miniPadding; x < newWidth; x++) { if (bitMatrix.get(x + left, y + top)) { newBitMatrix.setRegion(x, y, pointSize, pointSize); } } } MatrixToImageWriter.writeToStream(newBitMatrix, format, os); } catch (Exception e) { LOG.error(null, e); } } }