生成二維碼的時候,我們通常使用google.zxing包,使用google提供的工具類生成二維碼的時候通常會帶有白色邊框,有的人覺得白色的邊框很難看,那麼怎麼去除白色的邊框呢?
我們先把zxing的源碼下載下來。然後看下這個白邊是如果產生的。
首先是創建比特矩陣(位矩陣)的QR碼編碼的字符串的代碼:
new QRCodeWriter().encode(content, BarcodeFormat.QR_CODE, qrCodeSize, qrCodeSize, hintMap);
encode方法源碼如下:
public BitMatrix encode(String contents,
BarcodeFormat format,
int width,
int height,
Map<EncodeHintType,?> hints) throws WriterException {
if (contents.isEmpty()) {
throw new IllegalArgumentException("Found empty contents");
}
if (format != BarcodeFormat.QR_CODE) {
throw new IllegalArgumentException("Can only encode QR_CODE, but got " + format);
}
if (width < 0 || height < 0) {
throw new IllegalArgumentException("Requested dimensions are too small: " + width + 'x' +
height);
}
ErrorCorrectionLevel errorCorrectionLevel = ErrorCorrectionLevel.L;
int quietZone = QUIET_ZONE_SIZE;
if (hints != null) {
ErrorCorrectionLevel requestedECLevel = (ErrorCorrectionLevel) hints.get(EncodeHintType.ERROR_CORRECTION);
if (requestedECLevel != null) {
errorCorrectionLevel = requestedECLevel;
}
Integer quietZoneInt = (Integer) hints.get(EncodeHintType.MARGIN);
if (quietZoneInt != null) {
quietZone = quietZoneInt;
}
}
QRCode code = Encoder.encode(contents, errorCorrectionLevel, hints);
return renderResult(code, width, height, quietZone);
}
在方法的最後兩行我們看到調用renderResult方法,源碼如下
private static BitMatrix renderResult(QRCode code, int width, int height, int quietZone) {
ByteMatrix input = code.getMatrix();
if (input == null) {
throw new IllegalStateException();
}
int inputWidth = input.getWidth();
int inputHeight = input.getHeight();
//以下兩行源碼是原始代碼中控制邊距的參數
//int qrWidth = inputWidth + (quietZone << 1);
//int qrHeight = inputHeight + (quietZone << 1);
//以下兩行源碼是修改後的控制邊距的參數
int qrWidth = inputWidth + 2;
int qrHeight = inputHeight + 2;
int outputWidth = Math.max(width, qrWidth);
int outputHeight = Math.max(height, qrHeight);
int multiple = Math.min(outputWidth / qrWidth, outputHeight / qrHeight);
// Padding includes both the quiet zone and the extra white pixels to accommodate the requested
// dimensions. For example, if input is 25x25 the QR will be 33x33 including the quiet zone.
// If the requested size is 200x160, the multiple will be 4, for a QR of 132x132. These will
// handle all the padding from 100x100 (the actual QR) up to 200x160.
int leftPadding = (outputWidth - (inputWidth * multiple)) / 2;
int topPadding = (outputHeight - (inputHeight * multiple)) / 2;
BitMatrix output = new BitMatrix(outputWidth, outputHeight);
for (int inputY = 0, outputY = topPadding; inputY < inputHeight; inputY++, outputY += multiple) {
// Write the contents of this row of the barcode
for (int inputX = 0, outputX = leftPadding; inputX < inputWidth; inputX++, outputX += multiple) {
if (input.get(inputX, inputY) == 1) {
output.setRegion(outputX, outputY, multiple, multiple);
}
}
}
return output;
}
修改代碼位置如下,具體想要使用多大的間距可以自行調整qrWidth 以及qrHeight :
測試類:
/**
* 二維碼生成和讀的工具類
*/
public class QRCodeUtil {
/**
* 生成包含字符串信息的二維碼圖片
*
* @param outputStream 文件輸出流路徑
* @param content 二維碼攜帶信息
* @param qrCodeSize 二維碼圖片大小
* @param imageFormat 二維碼的格式
* @throws WriterException
* @throws IOException
*/
public static boolean createQrCode(OutputStream outputStream, String content, int qrCodeSize, String imageFormat) throws WriterException, IOException {
//設置二維碼糾錯級別MAP
Hashtable<EncodeHintType, ErrorCorrectionLevel> hintMap = new Hashtable<EncodeHintType, ErrorCorrectionLevel>();
hintMap.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L); // 矯錯級別
QRCodeWriterUtil qrCodeWriterUtil = new QRCodeWriterUtil();
//創建比特矩陣(位矩陣)的QR碼編碼的字符串
BitMatrix byteMatrix = qrCodeWriterUtil.encode(content, BarcodeFormat.QR_CODE, qrCodeSize, qrCodeSize, hintMap);
// 使BufferedImage勾畫QRCode (matrixWidth 是行二維碼像素點)
int matrixWidth = byteMatrix.getWidth();
BufferedImage image = new BufferedImage(matrixWidth - 20, matrixWidth - 20, BufferedImage.TYPE_INT_RGB);
image.createGraphics();
Graphics2D graphics = (Graphics2D) image.getGraphics();
graphics.setColor(Color.WHITE);
graphics.fillRect(0, 0, matrixWidth, matrixWidth);
// 使用比特矩陣畫並保存圖像
graphics.setColor(Color.BLACK);
for (int i = 0; i < matrixWidth; i++) {
for (int j = 0; j < matrixWidth; j++) {
if (byteMatrix.get(i, j)) {
graphics.fillRect(i - 10, j - 10, 1, 1);
}
}
}
return ImageIO.write(image, imageFormat, outputStream);
}
/**
* 讀二維碼並輸出攜帶的信息
*/
public static void readQrCode(InputStream inputStream) throws IOException {
//從輸入流中獲取字符串信息
BufferedImage image = ImageIO.read(inputStream);
//將圖像轉換爲二進制位圖源
LuminanceSource source = new BufferedImageLuminanceSource(image);
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
QRCodeReader reader = new QRCodeReader();
Result result = null;
try {
result = reader.decode(bitmap);
} catch (ReaderException e) {
e.printStackTrace();
}
System.out.println(result.getText());
}
/**
* 測試代碼
*
* @throws Exception
*/
public static void main(String[] args) throws Exception {
String fileName = "F:\\tmp" + StringUtils.generateUUID() + ".jpg";
File workFile = new File(fileName);
createQrCode(new FileOutputStream(workFile), "https://www.baidu.com", 500, "JPEG");
readQrCode(new FileInputStream(ResourceUtils.getFile(fileName)));
}
}
測試結果: