使用zxing生成二维码去除空白区域方法
通常我们生成二维码需要做以下配置
-
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);
-
}
-
}