一.概述
1)各类码图如二维码,验证码此类码图的生成,实际原理就是后台通过某种规则去生成图片流,将图片流返回给前端后,前端进行显示。后续内容将展开BufferedImage的实际应用。
2)此篇文章来自我的有道云笔记,耗时一周左右的摸索总结测试,以及看了相关的其他博主所写,根据自己的测试和探索,最终编写了自己的工具类。地址:我的有道云笔记链接
二.BufferedImage
1)是码图相关的一种非常重要的类,在各类码最终会转成此对象,返回到前端。
2)BufferImagTool是一个处理图片资源操作图片的类。下述将展示相关操作。
背景操作
没有在案例中使用到的方法,都有备注,阅读即可明白。
①案例一
如何通过此工具类生成一张全红的图呢?
BufferImagTool tool = new BufferImagTool();
try {
//1.设置背景色,画板的最终背景色要在画板初始化之前设置
//2.初始化画板
//3.获取最终的图流
BufferedImage image = tool.setBackgroundColor(Color.red)
.initBufferImage(200, 200, BufferImagTool.TYPE_INT_BGR)
.getImage();
ImageIO.write(image,"JPEG",response.getOutputStream());
} catch (Exception e) {
e.printStackTrace();
}
②案例二
BufferImagTool tool = new BufferImagTool();
try {
//1.设置背景色
BufferedImage image = tool.setBackgroundColor(Color.red)
//2.初始化画板
.initBufferImage(200, 200, BufferImagTool.TYPE_INT_BGR)
//3.设置备用的背景色
.setBackgroundColor(Color.blue)
//4.左上角插入一块背景
.insertBackGround(0f,0f,0.3f,0.3f)
//5.左下角插入一块背景
.insertBackGround(0f,0.7f,0.3f,0.3f)
//6.右上角插入一块背景
.insertBackGround(0.7f,0f,0.3f,0.3f)
//7.右下角插入一块背景
.insertBackGround(0.7f,0.7f,0.3f,0.3f)
.getImage();
ImageIO.write(image,"JPEG",response.getOutputStream());
} catch (Exception e) {
e.printStackTrace();
}
线操作
①案例一
BufferImagTool tool = new BufferImagTool();
try {
//1.设置背景色
BufferedImage image = tool.setBackgroundColor(Color.red)
//2.初始化画板
.initBufferImage(200, 200, BufferImagTool.TYPE_INT_BGR)
//3.设置当前备用的线条颜色
.setLineColor(Color.BLACK)
//4.从左上角画到右下角,取消随机色
.insertOneLine(0f,0f,1f,1f,false)
//5.设置当前的备用颜色
.setLineColor(Color.white)
//6.从左下角到右上角,取消随机色
.insertOneLine(0f,1f,1f,0f,false)
.getImage();
ImageIO.write(image,"JPEG",response.getOutputStream());
} catch (Exception e) {
e.printStackTrace();
}
②案例二
干扰线
BufferImagTool tool = new BufferImagTool();
try {
//1.设置背景色
BufferedImage image = tool.setBackgroundColor(Color.white)
//2.初始化画板
.initBufferImage(200, 200, BufferImagTool.TYPE_INT_BGR)
//3.使用随机色插入线条,位置也是随机的
.insertLines(50)
.getImage();
ImageIO.write(image,"JPEG",response.getOutputStream());
} catch (Exception e) {
e.printStackTrace();
}
字符串操作
BufferImagTool tool = new BufferImagTool();
try {
//1.设置背景色
BufferedImage image = tool.setBackgroundColor(Color.white)
.initBufferImage(200,200,BufferImagTool.TYPE_INT_BGR)
.insertString(0.5f,0.5f,"hello world")
.getImage();
ImageIO.write(image,"JPEG",response.getOutputStream());
} catch (Exception e) {
e.printStackTrace();
}
前端内容
前端写法都相似,通过get请求将后台数据流直接交给dom组件处理即可。
<div id="app">
<h1>hello world</h1>
<img :src="src1" alt="我的画板" height="50" width="50" @click="update1">
</div>
...
data(){
return {
src1:'/test/d01',
}
},
methods:{
update1(){
//1.需要设置一个随机参数来改变这个URL,否则H5不会重新渲染图片
this.src1 = this.src1+"?time="+Math.random();
},
...
三.验证码
在上述的BufferImagTool的应用背景下,验证码的生成显得非常简单。
案例:
BufferImagTool tool = new BufferImagTool();
try {
//1.设置背景色
BufferedImage image = tool.initBufferImage(100,100,BufferImagTool.TYPE_INT_BGR)
//2.设置需要的编码字符数量
.setVeri_CodeNum(5)
//3.设置干扰线
.insertLines(50,true)
//4.设置字体大小
.setFontStyle(30)
//5.插入编码
.insertVeriCode()
.getImage();
System.out.println("code = " + tool.getVeri_Code());
ImageIO.write(image,"JPEG",response.getOutputStream());
} catch (Exception e) {
e.printStackTrace();
}
四.二维码
二维码相对来说更复杂,需要使用到谷歌的依赖包,
此处使用了另一个自己封装的工具类QRCodeTool。
后续有二维码的大量详细说明
简要概述
1)二维码的种类非常多,此封装类把写到的二维码类型都测试过,没有通过的类型,请不要使用。
2)二维码的初始化需要一个type来制定是哪种类型二维码
3)二维码的示例比较简洁,具体的细节写在最后一章的工具类总结里
<!-- 二维码生成依赖包 -->
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
<version>3.3.0</version>
</dependency>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>javase</artifactId>
<version>3.3.0</version>
</dependency>
①案例一
QRCodeTool tool = new QRCodeTool();
BufferedImage qrCode = tool.setQrType(QRCodeTool.QRTYPE_QR_CODE)
.setQrCodeVersion(1)
.getQRCode();
ImageIO.write(qrCode,"JPEG",response.getOutputStream());
②案例二
插入图片,插入自定义内容,此处注意点较多,都写在代码注释里
QRCodeTool tool = new QRCodeTool();
BufferedImage qrCode = tool.setQrType(QRCodeTool.QRTYPE_QR_CODE)
.setQrCodeVersion(1)
.getQRCode();
ImageIO.write(qrCode,"JPEG",response.getOutputStream());
BufferImagTool btool1 = new BufferImagTool();
BufferImagTool btool2 = new BufferImagTool();
BufferedImage imge1 = btool1.initBufferImage(new File(pathHelper.getResourcesPath()+"/img/1.jpg"))
.getImage();
BufferedImage imge2 = btool2
.initBufferImage(qrCode)
.insertImage(imge1,0.33f,0.33f,0.33f,0.33f)
.getImage();
ImageIO.write(qrCode,"JPEG",response.getOutputStream());
什么是二维码
不要以为二维码就是你认知中的二维码,实际上他的类型和应用超出你的想象!!!
各类二维码及其实现
下面展示的是使用谷歌依赖后,各类二维码的生成关键语句。
01.AZTEC
①Aztec Code是1995年,由Hand HeldProducts公司的Dr. Andrew Longacre设计。它是一种高容量的二维条形码格式。它可以对ASCII和扩展ASCII码进行编码。当使用最高容量和25%的纠错级别的時候,Aztec可以对3000个字符或者3750个数字进行编码
Aztec的矩阵大小在15 X 15和151 X 151之间变化。每个最小单位非黑即白。它独特的位于正中的模式识别标志和安置算法使Aztec看起来像个旋涡一样。
Aztec打印解决方案允许用户选择大小和纠错级别。一共有36中不同的格式供选择,此外还有19种纠错级别可供选择,默认纠错级别是5级23%。高纠错级别意味着更少的数据容量和更小的误码机会。效果如下:
②通常用于:机票和其他旅行文档以及汽车登记文档。还可以用于医院的患者识别,或识别药物、样本以及与特定患者相关的其他物品。
③代码示例
//1.所有类型二维码的通用配置
HashMap<EncodeHintType, Object> configs = new HashMap<>();
//1.1 定义字符集
configs.put(EncodeHintType.CHARACTER_SET,CHARSET);
//1.2 设置容错等级
//configs.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M);
//1.3 设置二维码的外边距宽度,外边距部分会用白色进行填充
configs.put(EncodeHintType.MARGIN,10);
//1.AZTEC编码相关的配置,固定值
//2.不要设置容错
configs.put(EncodeHintType.AZTEC_LAYERS,-1);
BitMatrix qrObj = null;
try {
qrObj = new MultiFormatWriter().encode(qrContent, qrType, width, height, configs);
} catch (WriterException e) {
e.printStackTrace();
}
//3.2 采用黑白两色
BufferedImage img = MatrixToImageWriter.toBufferedImage(qrObj, new MatrixToImageConfig(Color.BLACK.getRGB(), Color.WHITE.getRGB()));
02.Codabar
①Codabar是由Monarch Marking Systems在1972年研制的条码。它是在"2 of 5"后早期阶段引入的条码。注意他的编码集是有限的!!!
②代码示例
没有特殊点,需要注意是有限字符
//1.所有类型二维码的通用配置
HashMap<EncodeHintType, Object> configs = new HashMap<>();
//1.1 定义字符集
configs.put(EncodeHintType.CHARACTER_SET,CHARSET);
//1.2 设置容错等级
//configs.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M);
//1.3 设置二维码的外边距宽度,外边距部分会用白色进行填充
configs.put(EncodeHintType.MARGIN,10);
//1.AZTEC编码相关的配置,固定值
BitMatrix qrObj = null;
try {
qrObj = new MultiFormatWriter().encode(qrContent, qrType, width, height, configs);
} catch (WriterException e) {
e.printStackTrace();
}
//3.2 采用黑白两色
BufferedImage img = MatrixToImageWriter.toBufferedImage(qrObj,
new MatrixToImageConfig(Color.BLACK.getRGB(),
Color.WHITE.getRGB()));
03.CODE_39
①CODE 39是 Intermec公司在1975年研制成功的。包括数字、字母和一些符号在内,条码共包括43个字符。
②场景:由于可以处理字母,CODE 39在工业领域必不可少,用于汽车、电子等工厂自动化行业。在美国,汽车工业行动组织已经对其进行了标准化。
③代码示例,无特殊配置
//1.所有类型二维码的通用配置
HashMap<EncodeHintType, Object> configs = new HashMap<>();
//1.1 定义字符集
configs.put(EncodeHintType.CHARACTER_SET,CHARSET);
//1.2 设置容错等级
//configs.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M);
//1.3 设置二维码的外边距宽度,外边距部分会用白色进行填充
configs.put(EncodeHintType.MARGIN,10);