编码前的准备:
goole生成二维码的依赖:
<!--google生成二维码的依赖-->
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>javase</artifactId>
<version>3.0.0</version>
</dependency>
使用阿里的fastjson jar包:
<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.68</version>
</dependency>
(使用fastjson,可以方便地完成 json对象和 json字符串的相互转化。)
使用Java生成一个二维码,主要依赖的是google的zxing类库。他底层实现了二维码生成的策略,我们做的仅仅是调用它的api,帮助我们生成二维码对象,最终这个二维码对象被我们用文件流来写入到磁盘。
生成一个二维码,需要哪些东西呢?
我们生活中最常见的二维码,它们其实都是用二维码的形式去刻画一个字符串。所有的请求,也就是url,它们也全是字符串。
那么字符串必然是生成二维码的一个必要条件。此外,我们还需要二维码的宽度和高度,二维码的字符集以及二维码的颜色,外边距(留白),纠错等级等等,都可以自行设计。
zxing包中的MultiFormatWriter
类是我们生成二维码的核心工具类。我们主要使用它的encode
方法,用来将要封装的字符串内容转变为二维码对象。
但是要注意MultiFormatWriter功能很强大,他不仅可以帮我们生成二维码,还可以生成条形码,其他各种各种的码。那么我们就得提供一个参数来告诉MultiFormatWriter我们要生成的码的类型是二维码,即QRCode。
还有就是,为了让封装的字符串支持中文显示,我们设置字符集,设置万国码即“UTF-8”。设置编码同样是采用传参的方式。
以上都是生成一个二维码的最基本条件。即:
1、字符串(内容content)
2、码的格式(ORCODE)
3、宽度(width)
4、高度(height)
5、字符集(它作为参数要封装在Map集合里)
有了以上4个条件,我们完全可以生成二维码了。
附:现实中的二维码,比如微信支付中的二维码,它使用的字符串是json格式的字符串。
为了模拟现实场景,我们才需要导入fastjson来帮我们快速生成json格式的字符串。(实际上使用任何字符串都是可以的),也就是说,仅仅生成二维码,fastjson不是必须的。
好,一通废话讲完,来看看代码,一会再来慢慢写废话。
Java实现:
public class ORCode {
@Test
public void generateORCode() throws WriterException, IOException {
//生成一个二维码
//定义一个json格式的字符串,使用fastjson(它能完成json字符串和json对象的相互转化)
//1.创建一个jsonObject对象
JSONObject jsonObject = new JSONObject();
//2.给jsonObject对象中存放数据
jsonObject.put("username","root");
jsonObject.put("password","123456");
jsonObject.put("sex","男");
jsonObject.put("address","北京市");
//json对象转换为json格式的字符串
String contents = jsonObject.toString();
//System.out.println(jsonString);
//二维码的宽高
int width = 200;
int height = 200;
//创建一个map集合,存放字符集
Map<EncodeHintType,Object> hints = new HashMap<EncodeHintType,Object>();
hints.put(EncodeHintType.CHARACTER_SET,"UTF-8");
//定义一个矩阵对象,生成二维码的关键代码:实例化一个矩阵对象
BitMatrix bitMatrix = new MultiFormatWriter().encode(contents, BarcodeFormat.QR_CODE,width,height,hints);
//图片的路径
String filePath = "E://";
//图片的名称
String fileName = "QRCode1.jpg";
//创建一个路径对象
Path path = FileSystems.getDefault().getPath(filePath+fileName);
//将矩阵对象转化为图片
MatrixToImageWriter.writeToPath(bitMatrix,"jpg",path);
System.err.println("二维码生成完毕");
}
}
看到了吗,代码很简单,关键代码就一行:
BitMatrix bitMatrix = new MultiFormatWriter().encode(contents, BarcodeFormat.QR_CODE,width,height,hints);
然后我们来了解一些关于二维码的小常识:
我们日常所使用的二维码,也就是时下最流行的二维码,它叫做ORCode
,是日本发明的。
而早期的二维码,有一个叫做PDF417
,它是美国发明的,目前也有人在使用。
而中国发明的二维码,叫做汉信码
。
DM码,也是美国发明的。
4种二维码对比:
另外,二维码是分纠错等级的。也是说我这个二维码丢失了一部分,或者说扫描的不全,有多大程度上保证信息完整而不会出错呢?
纠错等级分4级,纠错等级越高,纠错能力越强,分的像素点就越多,二维码看起来更密集,丢失部分后保证完整性的可能性越大。
纠错等级 | 含义 | 最大可丢失 |
---|---|---|
L | Low | 7% |
M | Middle | 15% |
Q | Quartered | 25% |
H | High | 30% |
还有,我们可以自定义二维码一些属性,来使得我们的二维码尽可能更满足实际需求。
比如,设置二维码的margin(外边距),维持一定的留白。
还要设置一下纠错等级。
这些信息,我们都同编码格式一样,放在Map集合中存储。
我们重新写一份代码来生成二维码:
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
public class GenerateORCode {
public static void main(String[] args) throws WriterException, IOException {
MultiFormatWriter mfw = new MultiFormatWriter();
//mfw.encode()
String content = "今天下雨了,很冷";
BarcodeFormat codeType = BarcodeFormat.QR_CODE;
int width = 666;
int height = 666;
Map<EncodeHintType,Object> map = new HashMap();//用来存储二维码的其他信息,尽管这些信息可能并不是生成二维码必要条件
map.put(EncodeHintType.CHARACTER_SET,"UTF-8");
map.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M);//设置纠错等级为M
map.put(EncodeHintType.MARGIN,2);//设置外边距为2
//还可以存放其他很多信息·····
//生成二维码对象
BitMatrix bitMatrix = mfw.encode(content, codeType, width, height, map);
//利用java.awt.image包下的BufferedImage,利用它设置生成图片的每个像素的颜色
BufferedImage image = new BufferedImage(width,height,BufferedImage.TYPE_INT_BGR);
int Green = Color.GREEN.getRGB();
int Yellow = Color.YELLOW.getRGB();
for (int x = 0;x<width;x++){
for (int y = 0;y<height;y++){
image.setRGB(x,y,bitMatrix.get(x,y)?Green:Yellow);
}
}
//需要将上面的image写入文件
File file = new File("E://test//QRcode.jpg");
ImageIO.write(image,"jpg",file);
System.out.println("二维码生成完毕");
}
}
附:关于 fastjson的一些说明
fastjson.jar是阿里巴巴开发的一款专门用于Java开发的包,可以方便的实现json对象与JavaBean对象的转换,实现JavaBean对象与json字符串的转换,实现json对象与json字符串的转换。除了这个fastjson以外,还有Google开发的Gson包,其他形式的如net.sf.json包,都可以实现json的转换。方法名称不同而已,最后的实现结果都是一样的。
1、javaBean 转化为 jsonString
String str1=JSON.toJSONString(student);
2、jsonString 转化为 javaBean
Student stu1=JSON.parseObject(str1,Student.class);
3、javaBean 转化为 jsonObject
JSONObject jsonObject1=(JSONObject)JSON.toJSON(student);
4、jsonObject 转化为 javaBean
Student student2=JSON.toJavaObject(jsonObject1, Student.class);
5、javaBean 转化为 jsonArray
JSONArray jsonArrays=(JSONArray)JSON.toJSON(stulist);
6、jsonArry 转化为 javalist
for(int i=0;i<jsonArrays.size();i++){
Student student3=JSON.toJavaObject(jsonArrays.getJSONObject(i), Student.class);
myList.add(student3);
}
7、jsonObject 转化为 jsonString
String str4=JSON.toJSONString(jsonObject1);
8、jsonString 转化为 jsonObject
JSONObject jso1=JSON.parseObject(str1);
9、jsonString 转化为 jsonArray
JSONArray jArray=JSON.parseArray(JSON.toJSONString(stulist));