Java二维码学习
使用Java语言生成二维码有以下方式,一是谷歌的zxing,二是基于zxing实现的qrcode开源项目,三是基于zxing实现的qrgen开源项目
一 zxing
谷歌的zxing技术生成二维码,是MultiFormatWriter多写格式书写器生成BitMatrix位矩阵,然后将位矩阵的信息在BufferedImage中设置二维码图片,最后由ImageIO将二维码图片写出到文件。
1.1 生成普通二维码
<dependencies><!-- 二维码操作相关依赖 --><dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.4.0</version></dependency><dependency><groupId>com.google.zxing</groupId><artifactId>javase</artifactId><version>3.4.0</version></dependency><!-- word文档操作相关依赖 --><dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>5.2.3</version></dependency><dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>5.2.3</version></dependency>
</dependencies>
public static void main(String[] args) throws WriterException, IOException, InvalidFormatException {String str = "Yesterday Once More";final String CHARSET = "UTF-8";final int QRCODE_SIZE = 100;// EncodeHintType编码提示类型, 用来设置二维码图片的相关参数// Map集合使用Hashtable和HashMap都可以// Hashtable是线程安全的,但同步会带来性能损耗// HashMap是非线程安全,但在单线程环境下效率更高Map<EncodeHintType, Object> hints = new Hashtable<>();hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M);hints.put(EncodeHintType.CHARACTER_SET, CHARSET);hints.put(EncodeHintType.MARGIN, 0);// MultiFormatWriter多格式书写器, 是二维码生成类// BitMatrix位矩阵, 是布尔型二维数组, 表示二维码矩阵的数据结构BitMatrix bitMatrix = new MultiFormatWriter().encode(str, BarcodeFormat.QR_CODE, QRCODE_SIZE, QRCODE_SIZE, hints);int width = bitMatrix.getWidth();int height = bitMatrix.getHeight();// BufferedImage图像类, 提供了对图像像素级别的访问和修改BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);for (int i = 0; i < width; i++) {for (int j = 0; j < height; j++) {bufferedImage.setRGB(i, j, bitMatrix.get(i, j) ? 0x000000 : 0xFFFFFF);}}ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();// ImageIO标准图像输入输出工具类, 用于读取、写入和处理各种格式的图像文件ImageIO.write(bufferedImage, "jpg", byteArrayOutputStream);ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());// XWPFDocument类位于Apache POI库中的poi-ooxml模块中, 用于操作Microsoft Word(.docx)文档XWPFDocument document = new XWPFDocument();XWPFRun run = document.createParagraph().createRun();run.addPicture(byteArrayInputStream, XWPFDocument.PICTURE_TYPE_JPEG, "mango", Units.toEMU(128), Units.toEMU(128));FileOutputStream fileOutputStream = new FileOutputStream("D:\\mango.docx");document.write(fileOutputStream);fileOutputStream.close();
}
生成的二维码如下:
EncodeHintType编码提示类型是一个枚举类,用来设置二维码图片的相关属性,使用EncodeHintType作为key,Object作为value的Hashtable,常用设置如下:
EncodeHintType.ERROR_CORRECTION设置二维码的容错率,value值ErrorCorrectionLevel也是枚举类,由L(7%)、M(15%)、Q(25%)和H(30%)四个可选项;
EncodeHintType.CHARACTER_SET设置字符集,value值可以设置UTF-8;
EncodeHintType.MARGIN设置二维码周边留白大小,value值是一个整型数值;
MultiFormatWriter多格式书写器, 是二维码生成类,MultiFormatWriter的encode方法可以将指定文本生成BitMatrix位矩阵对象,encode方法定义如下
public BitMatrix encode(String contents, BarcodeFormat format, int width, int height, Map<EncodeHintType, ?> hints),参数解释:
String contents:要生成二维码的文本内容;
BarcodeFormat format:指定码的格式,BarcodeFormat是枚举值,常用枚举值有QR_CODE(通用二维码,支持文本和链接URL),CODE_128(条形码,支持物流和商品管理)和EAN_13(国际商品编码,广泛用于零售商品);
int width:二维码的宽度(像素);
int height:二维码的高度(像素);
Map<EncodeHintType, ?> hints:二维码图片的相关属性,Map集合使用Hashtable和HashMap都可以,Hashtable是线程安全的,但同步会带来性能损耗,HashMap是非线程安全,但在单线程环境下效率更高;
BitMatrix表示二维码矩阵的数据结构,由0和1构成的布尔型二维数组,常用于将编码后的信息转化为矩阵形式,用于存储和处理生成二维码图像所需的二进制信息,通过对BitMatrix对象的构建和操作,最终生成一个可被扫描解码的二维码图像,BitMatrix常用API:
public int getHeight():获取二维码矩阵高度;
public int getWidth():获取二维码矩阵宽度;
public boolean get(int x, int y):根据x,y的坐标获取矩阵中该坐标的值,结果是true(有值)或者false(无值);
BufferedImage缓冲区图像类,将一幅图片加载到内存中(BufferedImage生成的图片在内存里有一个图像缓冲区),在缓冲区操作图片资源,而且提供获得绘图对象、图像缩放、选择图像平滑度等功能,通常用来做图片大小变换、图片变灰、设置透明不透明等;
ImageIO是Java的标准图像输入输出工具类,用于读取、写入和处理各种格式的图像文件;
1.2 生成彩色二维码
在设置BufferedImage对象的setRGB方法中,设置RGB颜色时,指定需要的颜色即可,譬如生成前景色为纯蓝色的二维码,使用0x0000FF进行RGB设置
// BufferedImage图像类, 提供了对图像像素级别的访问和修改
BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
for (int i = 0; i < width; i++) {for (int j = 0; j < height; j++) {bufferedImage.setRGB(i, j, bitMatrix.get(i, j) ? 0x0000FF : 0xFFFFFF);}
}
1.3 生成带logo的二维码
public static void main(String[] args) throws WriterException, IOException, InvalidFormatException {String str = "Yesterday Once More";final String CHARSET = "UTF-8";final int QRCODE_SIZE = 100;// EncodeHintType编码提示类型, 用来设置二维码图片的相关参数// Map集合使用Hashtable和HashMa