通常我们生成二维码需要做以下配置
-
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); -
} -
}