简介
本文主要介绍使用Java生成二维码,可以实现自定义二维码名称以及二维码内容,也可以设置生成二维码的长和宽,根据测试结论内容越多从而生成二维码的密度越高,同时优化了二维码的纠错能力以及防止乱码,也优化了二维码的留白问题,可实现二维码四周无留白或者留白的间距,废话不多说,接下来看一下如何实现的吧!Go,Go,Go~~~
生成二维码
引入pom依赖
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>javase</artifactId>
<version>3.4.1</version>
<scope>compile</scope>
</dependency>
封装工具类
方式一
将二维码输出到本地默认位置
public static void main(String[] args) throws WriterException, IOException {
// 生成二维码图片到本地(方式一)
String text = "二维码内容";
QRCodeWriter qrCodeWriter = new QRCodeWriter();
//定义map集合,用于存放二维码的一些其他设置
Map<EncodeHintType, Object> map = Maps.newHashMap();
//EncodeHintType.ERROR_CORRECTION:二维码的纠错能力
//L:Low 7% M:Middle 15% Q:Quartereed 25% H:High 30%
map.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
//设置编码,防止乱码
map.put(EncodeHintType.CHARACTER_SET,"UTF-8");
//设置留白
map.put(EncodeHintType.MARGIN,0);
BitMatrix bitMatrix = qrCodeWriter.encode(text, BarcodeFormat.QR_CODE, QR_CODE_SIZE, QR_CODE_SIZE, map);
Path file = FileSystems.getDefault().getPath("qrcode.png");
MatrixToImageWriter.writeToPath(bitMatrix, "PNG", file);
System.out.println("二维码已生成:" + file.toAbsolutePath());
}
方式二
将二维码输出到本地默认位置
// 所引用的方法 在文章的下方
public static void main(String[] args) throws WriterException, IOException {
// 生成二维码图片到本地(方式二)
String text = "二维码内容";
QRCodeWriter qrCodeWriter = new QRCodeWriter();
//定义map集合,用于存放二维码的一些其他设置
Map<EncodeHintType, Object> map = Maps.newHashMap();
//EncodeHintType.ERROR_CORRECTION:二维码的纠错能力
//L:Low 7% M:Middle 15% Q:Quartereed 25% H:High 30%
map.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
//设置编码,防止乱码
map.put(EncodeHintType.CHARACTER_SET,"UTF-8");
//设置留白
map.put(EncodeHintType.MARGIN,0);
BitMatrix bitMatrix = qrCodeWriter.encode(text, BarcodeFormat.QR_CODE, QR_CODE_SIZE, QR_CODE_SIZE, map);
BufferedImage bufferedImage = deleteWhite(bitMatrix);
// BufferedImage bufferedImage = MatrixToImageWriter.toBufferedImage(bitMatrix);
byte[] bytes = bufferedImageToByteArray(bufferedImage);
MultipartFile multipartFile = FilesUtil.byteArrayToMultipartFile(bytes, "qrcode.png", "qrcode.png", ContentType.IMAGE_JPEG.toString());
Path path = FileSystems.getDefault().getPath(multipartFile.getName());
File file = path.toFile();
multipartFile.transferTo(file);
System.out.println("二维码已生成:" + path.toAbsolutePath());
}
将二维码四周的白色边距去掉方法
/**
* 将二维码四周的白色边距去掉
* @param matrix 二维码对象
* @return 二维码
*/
private static BufferedImage deleteWhite(BitMatrix matrix) {
int[] rec = matrix.getEnclosingRectangle();
int resWidth = rec[2] + 1;
int resHeight = rec[3] + 1;
BitMatrix resMatrix = new BitMatrix(resWidth, resHeight);
resMatrix.clear();
for (int i = 0; i < resWidth; i++) {
for (int j = 0; j < resHeight; j++) {
if (matrix.get(i + rec[0], j + rec[1]))
resMatrix.set(i, j);
}
}
int width = resMatrix.getWidth();
int height = resMatrix.getHeight();
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, resMatrix.get(x, y) ? BLACK
: WHITE);
}
}
return image;
}
将BufferedImage转换为Byte数组方法
/**
* 将BufferedImage转换为Byte数组
* @param image BufferedImage对象
* @return byte数组
* @throws IOException io异常
*/
public static byte[] bufferedImageToByteArray(BufferedImage image) throws IOException {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
ImageIO.write(image, "png", outputStream);
return outputStream.toByteArray();
}
将byte数组转为MultipartFile文件对象
/**
* 将byte数组转为MultipartFile文件对象
* @param byteArray byte数组
* @param fileName 文件名称
* @param originalFilename 源文件名称
* @param contentType 文件类型
* @return MultipartFile文件对象
*/
public static MultipartFile byteArrayToMultipartFile(byte[] byteArray, String fileName, String originalFilename, String contentType) {
InputStream inputStream = new ByteArrayInputStream(byteArray);
try {
MultipartFile multipartFile = new MockMultipartFile(fileName, originalFilename, contentType, inputStream);
return multipartFile;
} catch (IOException e) {
logger.error("byteArrayToMultipartFile ---fileName:{} ---ex:{}", fileName, ExceptionUtils.getErrorStackTrace(e));
}
return null;
}
二维码工具类
package com.uyaogui.common.core.util;
import com.google.common.collect.Maps;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.WriterException;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import com.uyaogui.common.core.exception.ExceptionUtils;
import org.apache.http.entity.ContentType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.multipart.MultipartFile;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.Path;
import java.util.Map;
import static com.google.zxing.client.j2se.MatrixToImageConfig.BLACK;
import static com.google.zxing.client.j2se.MatrixToImageConfig.WHITE;
public class QRCodeUtils {
private static final Logger logger = LoggerFactory.getLogger(QRCodeUtils.class);
// 二维码大小(长、宽)
private static final int QR_CODE_SIZE = 256;
/**
* 获取二维码文件
* @param text 二维码内容
* @param fileName 二维码文件名称
* @return 二维码文件对象
*/
public static MultipartFile getQRCodeMultipartFile(String text, String fileName){
logger.info("getQRCodeMultipartFile ---text:{},fileName:{}", text, fileName);
QRCodeWriter qrCodeWriter = new QRCodeWriter();
//定义map集合,用于存放二维码的一些其他设置
Map<EncodeHintType, Object> map = Maps.newHashMap();
//EncodeHintType.ERROR_CORRECTION:二维码的纠错能力
//L:Low 7% M:Middle 15% Q:Quartereed 25% H:High 30%
map.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
//设置编码,防止乱码
map.put(EncodeHintType.CHARACTER_SET,"UTF-8");
//设置留白
map.put(EncodeHintType.MARGIN,0);
try {
BitMatrix bitMatrix = qrCodeWriter.encode(text, BarcodeFormat.QR_CODE, QR_CODE_SIZE, QR_CODE_SIZE, map);
BufferedImage bufferedImage = deleteWhite(bitMatrix);
byte[] bytes = bufferedImageToByteArray(bufferedImage);
return FilesUtil.byteArrayToMultipartFile(bytes, fileName, fileName, ContentType.IMAGE_JPEG.toString());
} catch (Exception e) {
logger.error("getQRCodeMultipartFile ---text:{},fileName:{} ---ex:{}", text, fileName, ExceptionUtils.getErrorStackTrace(e));
}
return null;
}
public static void main(String[] args) throws WriterException, IOException {
// // 生成二维码图片到本地(方式一)
// String text = "二维码内容";
// QRCodeWriter qrCodeWriter = new QRCodeWriter();
// //定义map集合,用于存放二维码的一些其他设置
// Map<EncodeHintType, Object> map = Maps.newHashMap();
// //EncodeHintType.ERROR_CORRECTION:二维码的纠错能力
// //L:Low 7% M:Middle 15% Q:Quartereed 25% H:High 30%
// map.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
// //设置编码,防止乱码
// map.put(EncodeHintType.CHARACTER_SET,"UTF-8");
// //设置留白
// map.put(EncodeHintType.MARGIN,0);
// BitMatrix bitMatrix = qrCodeWriter.encode(text, BarcodeFormat.QR_CODE, QR_CODE_SIZE, QR_CODE_SIZE, map);
// Path file = FileSystems.getDefault().getPath("qrcode.png");
// MatrixToImageWriter.writeToPath(bitMatrix, "PNG", file);
// System.out.println("二维码已生成:" + file.toAbsolutePath());
// 生成二维码图片到本地(方式二)
String text = "二维码内容";
QRCodeWriter qrCodeWriter = new QRCodeWriter();
//定义map集合,用于存放二维码的一些其他设置
Map<EncodeHintType, Object> map = Maps.newHashMap();
//EncodeHintType.ERROR_CORRECTION:二维码的纠错能力
//L:Low 7% M:Middle 15% Q:Quartereed 25% H:High 30%
map.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
//设置编码,防止乱码
map.put(EncodeHintType.CHARACTER_SET,"UTF-8");
//设置留白
map.put(EncodeHintType.MARGIN,0);
BitMatrix bitMatrix = qrCodeWriter.encode(text, BarcodeFormat.QR_CODE, QR_CODE_SIZE, QR_CODE_SIZE, map);
BufferedImage bufferedImage = deleteWhite(bitMatrix);
// BufferedImage bufferedImage = MatrixToImageWriter.toBufferedImage(bitMatrix);
byte[] bytes = bufferedImageToByteArray(bufferedImage);
MultipartFile multipartFile = FilesUtil.byteArrayToMultipartFile(bytes, "qrcode.png", "qrcode.png", ContentType.IMAGE_JPEG.toString());
Path path = FileSystems.getDefault().getPath(multipartFile.getName());
File file = path.toFile();
multipartFile.transferTo(file);
System.out.println("二维码已生成:" + path.toAbsolutePath());
}
/**
* 将二维码四周的白色边距去掉
* @param matrix 二维码对象
* @return 二维码
*/
private static BufferedImage deleteWhite(BitMatrix matrix) {
int[] rec = matrix.getEnclosingRectangle();
int resWidth = rec[2] + 1;
int resHeight = rec[3] + 1;
BitMatrix resMatrix = new BitMatrix(resWidth, resHeight);
resMatrix.clear();
for (int i = 0; i < resWidth; i++) {
for (int j = 0; j < resHeight; j++) {
if (matrix.get(i + rec[0], j + rec[1]))
resMatrix.set(i, j);
}
}
int width = resMatrix.getWidth();
int height = resMatrix.getHeight();
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, resMatrix.get(x, y) ? BLACK
: WHITE);
}
}
return image;
}
/**
* 将BufferedImage转换为Byte数组
* @param image BufferedImage对象
* @return byte数组
* @throws IOException io异常
*/
public static byte[] bufferedImageToByteArray(BufferedImage image) throws IOException {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
ImageIO.write(image, "png", outputStream);
return outputStream.toByteArray();
}
}
文件对象转换工具类
package com.uyaogui.common.core.util;
import com.uyaogui.common.core.exception.ExceptionUtils;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.commons.CommonsMultipartFile;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
public class FilesUtil {
private static final Logger logger = LoggerFactory.getLogger(FilesUtil.class);
/**
* 根据网络URL获取文件流
* @param url 网络URL
* @return 文件流
*/
public static byte[] getFileStream(String url){
try {
URL httpUrl = new URL(url);
HttpURLConnection conn = (HttpURLConnection)httpUrl.openConnection();
conn.setRequestMethod("GET");
conn.setConnectTimeout(10 * 1000);
conn.setReadTimeout(10 * 1000);
InputStream inStream = conn.getInputStream();//通过输入流获取图片数据
byte[] btImg = readInputStream(inStream);//得到图片的二进制数据
inStream.close();
return btImg;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 文件对象转MultipartFile对象
* @param file 文件
* @return MultipartFile对象
*/
public static MultipartFile fileToMultipartFile(File file) {
FileItem fileItem = createFileItem(file);
return new CommonsMultipartFile(fileItem);
}
/**
* 根据File对象创建FileItem对象
* @param file File
* @return FileItem对象
*/
public static FileItem createFileItem(File file) {
FileItemFactory factory = new DiskFileItemFactory(16, null);
FileItem item = factory.createItem("textField", "text/plain", true, file.getName());
int bytesRead = 0;
byte[] buffer = new byte[8192];
try {
FileInputStream fis = new FileInputStream(file);
OutputStream os = item.getOutputStream();
while ((bytesRead = fis.read(buffer, 0, 8192)) != -1) {
os.write(buffer, 0, bytesRead);
}
os.close();
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
return item;
}
/**
* 得到文件的二进制数据,以二进制封装得到数据,具有通用性
*
* @param inStream
* @return
* @throws Exception
*/
public static byte[] readInputStream(InputStream inStream) throws Exception {
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
//创建一个Buffer字符串
byte[] buffer = new byte[1024];
//每次读取的字符串长度,如果为-1,代表全部读取完毕
int len = 0;
//使用一个输入流从buffer里把数据读取出来
while ((len = inStream.read(buffer)) != -1) {
//用输出流往buffer里写入数据,中间参数代表从哪个位置开始读,len代表读取的长度
outStream.write(buffer, 0, len);
}
//关闭输入流
inStream.close();
//把outStream里的数据写入内存
return outStream.toByteArray();
}
/**
* MultipartFile 转 File
*
* @param multipartFile
* @throws Exception
*/
public static File multipartFileToFile(MultipartFile multipartFile) {
File file = null;
//判断是否为null
if (multipartFile.equals("") || multipartFile.getSize() <= 0) {
return file;
}
//MultipartFile转换为File
InputStream ins = null;
OutputStream os = null;
try {
ins = multipartFile.getInputStream();
file = new File(multipartFile.getOriginalFilename());
os = new FileOutputStream(file);
int bytesRead = 0;
byte[] buffer = new byte[8192];
while ((bytesRead = ins.read(buffer, 0, 8192)) != -1) {
os.write(buffer, 0, bytesRead);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (os != null) {
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (ins != null) {
try {
ins.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return file;
}
/**
* 将byte数组转为MultipartFile文件对象
* @param byteArray byte数组
* @param fileName 文件名称
* @param originalFilename 源文件名称
* @param contentType 文件类型
* @return MultipartFile文件对象
*/
public static MultipartFile byteArrayToMultipartFile(byte[] byteArray, String fileName, String originalFilename, String contentType) {
InputStream inputStream = new ByteArrayInputStream(byteArray);
try {
MultipartFile multipartFile = new MockMultipartFile(fileName, originalFilename, contentType, inputStream);
return multipartFile;
} catch (IOException e) {
logger.error("byteArrayToMultipartFile ---fileName:{} ---ex:{}", fileName, ExceptionUtils.getErrorStackTrace(e));
}
return null;
}
}
结束语
以上就是本次介绍的二维码生成工具类,有需要的朋友们直接Ctrl+C、Ctrl+V
作者:筱白爱学习!!
欢迎关注转发评论点赞沟通,您的支持是筱白的动力!