🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
## 二维码 1. 在代码编制上巧妙地利用构成计算机内部逻辑基础的“0”、“1”比特流的概念,使用若干个与二进制相对应的几何形体来表示文字数值信息,通过图象输入设备或光电扫描设备自动识读以实现信息自动处理。 2. 在许多种类的二维条码中,常用的码制有: Data Matrix,MaxiCode, Aztec,QR Code, Vericode,PDF417,Ultracode,Code 49,Code 16K等, 3. QR code码是1994年由日本DW公司发明。QR来自英文「Quick Response」的缩写,即快速反应的意思,源自发明者希望QR码可让其内容快速被解码。QR码最常见于日本、韩国;并为目前日本最流行的二维空间条码。但二维码的安全性也正备受挑战,带有恶意软件和病毒正成为二维码普及道路上的绊脚石。发展与防范二维码的滥用正成为一个亟待解决的问题。 ![](https://box.kancloud.cn/dea6295e90c16a0080b06c0ae6ae5b27_1229x785.png) 纠错能力越高,二维码存储的信息就越少,对二维码的清晰度要求就越低。 ![](https://box.kancloud.cn/dbe41ebf7ea5fedc8e2e9417885407db_1023x632.png) ## 1. 生成二维码 ### 1.1 直接用MatrixToImageWriter写入文件或者流 ![](https://box.kancloud.cn/db6de5207b09c3da1f42e7bf5f16a4a4_860x447.png) * 有问题的 * 依赖 ~~~ <dependency> <groupId>com.google.zxing</groupId> <artifactId>core</artifactId> <version>3.3.0</version> </dependency> ~~~ ### 1.2 ~~~ package net.aexit.galaxy.earth.mediashare.qrcode; 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.image.BufferedImage; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; import java.util.Base64; import java.util.HashMap; /** * Created by dailin on 2017/11/30. * 生成二维码工具类 */ public class QrGenerator { private static final int BLACK = 0xFF000000; private static final int WHITE = 0xFFFFFFFF; private int width = 300; //二维码宽度 private int height = 300;//二维码高度 private String format = "png"; // 二维码图片保存格式 private String contents = ""; //扫描二维码时产生的内容 /** * 生成BitMatrix二维码 * @return BitMatrix */ public BitMatrix CreatQRCode() throws WriterException { //定义二维码的参数 HashMap hints = new HashMap(); hints.put(EncodeHintType.CHARACTER_SET, "utf-8"); hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M);//设置二维码的容错等级 hints.put(EncodeHintType.MARGIN, 2);//边距 return new MultiFormatWriter().encode(contents, BarcodeFormat.QR_CODE, width, height, hints); } public BufferedImage toBufferedImage(BitMatrix matrix) { int width = matrix.getWidth(); int height = matrix.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, matrix.get(x, y) ? BLACK : WHITE); } } return image; } /** * 将生产的二维码写入图片文件 * @param file * @throws IOException */ public void writeToFile(File file) throws IOException, WriterException { BitMatrix matrix = CreatQRCode(); BufferedImage image = toBufferedImage(matrix); if (!ImageIO.write(image, format, file)) { throw new IOException("Could not write an image of format " + format + " to " + file); } } /** * 将生成的二维码以二进制数组的形式返回 */ public byte[] writeToBytes() throws WriterException, IOException { BitMatrix matrix = CreatQRCode(); byte[] bytes = null; try(ByteArrayOutputStream byteArray = new ByteArrayOutputStream()){ BufferedImage image = toBufferedImage(matrix); if (!ImageIO.write(image, format, byteArray)) { throw new IOException("faild to write an image to bytes"); } bytes = byteArray.toByteArray(); } return bytes; } /** * 将生成的二维码以base64编码的形式返回 */ public String writeToBase64() throws WriterException, IOException { BitMatrix matrix = CreatQRCode(); String base64String=null; try(ByteArrayOutputStream byteArray = new ByteArrayOutputStream()){ BufferedImage image = toBufferedImage(matrix); if (!ImageIO.write(image, format, byteArray)) { throw new IOException("faild to write an image to bytes"); } byte[] bytes = byteArray.toByteArray(); base64String = Base64.getEncoder().encodeToString(bytes); } return base64String; } public int getWidth() { return width; } public void setWidth(int width) { this.width = width; } public int getHeight() { return height; } public void setHeight(int height) { this.height = height; } public String getFormat() { return format; } public void setFormat(String format) { this.format = format; } public String getContents() { return contents; } public void setContents(String contents) { this.contents = contents; } } ~~~ 2. 实体类 ~~~ package JavaTest.erweima; import javax.security.auth.Subject; /** * Created by dailin on 2017/11/30. */ public class StudentInfo { private String name ; private String IdCard ; private String CarType ; private String number; private int Subject_One_grade; private int Subject_One_total; private int Subject_Two_grade; private int Subject_Two_total; private int Subject_Three_grade; private int Subject_Three_total; private int Subject_Four_grade; private int Subject_Four_total; private Boolean IsGraduate; public Boolean getGraduate() { return IsGraduate; } public void setGraduate(Boolean graduate) { IsGraduate = graduate; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getIdCard() { return IdCard; } public void setIdCard(String idCard) { IdCard = idCard; } public String getCarType() { return CarType; } public void setCarType(String carType) { CarType = carType; } public String getNumber() { return number; } public void setNumber(String number) { this.number = number; } public int getSubject_One_grade() { return Subject_One_grade; } public void setSubject_One_grade(int subject_One_grade) { Subject_One_grade = subject_One_grade; } public int getSubject_One_total() { return Subject_One_total; } public void setSubject_One_total(int subject_One_total) { Subject_One_total = subject_One_total; } public int getSubject_Two_grade() { return Subject_Two_grade; } public void setSubject_Two_grade(int subject_Two_grade) { Subject_Two_grade = subject_Two_grade; } public int getSubject_Two_total() { return Subject_Two_total; } public void setSubject_Two_total(int subject_Two_total) { Subject_Two_total = subject_Two_total; } public int getSubject_Three_grade() { return Subject_Three_grade; } public void setSubject_Three_grade(int subject_Three_grade) { Subject_Three_grade = subject_Three_grade; } public int getSubject_Three_total() { return Subject_Three_total; } public void setSubject_Three_total(int subject_Three_total) { Subject_Three_total = subject_Three_total; } public int getSubject_Four_grade() { return Subject_Four_grade; } public void setSubject_Four_grade(int subject_Four_grade) { Subject_Four_grade = subject_Four_grade; } public int getSubject_Four_total() { return Subject_Four_total; } public void setSubject_Four_total(int subject_Four_total) { Subject_Four_total = subject_Four_total; } @Override public String toString() { String graduation = "未结业"; String NEW_LINE = System.getProperty("line.separator"); if (IsGraduate==true) graduation = "结业"; return "学员姓名:" + name + NEW_LINE + "学员身份证号:" + IdCard + NEW_LINE + "学员车型:" + CarType + NEW_LINE + "学员编号:" + number + NEW_LINE + "科目一:" + Subject_One_grade + "/" + Subject_One_total + NEW_LINE + "科目二:" + Subject_Two_grade + "/" + Subject_Two_total + NEW_LINE + "科目三:" + Subject_Three_grade + "/" + Subject_Three_total + NEW_LINE + "科目四:" + Subject_Four_grade + "/" + Subject_Four_total + NEW_LINE + "是否结业:" + graduation; } } ~~~ 3. 测试类 ~~~ package JavaTest.erweima; import com.google.zxing.common.BitMatrix; import java.io.*; /** * Created by dailin on 2017/11/30. */ public class test { public static void main(String[] args) { StudentInfo student = new StudentInfo(); student.setName("代林"); student.setIdCard("220122199108105513"); student.setCarType("大奔"); student.setNumber("123"); student.setSubject_One_grade(25); student.setSubject_One_total(100); student.setSubject_Two_grade(25); student.setSubject_Two_total(100); student.setSubject_Three_grade(25); student.setSubject_Three_total(100); student.setSubject_Four_grade(25); student.setSubject_Four_total(100); student.setGraduate(true); String str = student.toString(); File file = new File("C:\\Users\\Administrator\\Desktop\\dialin.png"); ErWeiMa erweima = new ErWeiMa(); erweima.setContents(str); try { erweima.writeToFile(file); // 写成图片文件 byte[] bytes = erweima.writeToStream(); OutputStream baos2 = new FileOutputStream("C:\\Users\\Administrator\\Desktop\\aixin.png"); baos2.write(bytes); } catch (Exception e) { e.printStackTrace(); } } } ~~~ ## 改正后 1. 底层工具类要抛出具体的异常,不要try catch拦截,否则上层无法捕捉错误信息 2. 没关闭流 ~~~ /** * 生成BitMatrix二维码 * @return BitMatrix */ public BitMatrix CreatQRCode() throws WriterException { //定义二维码的参数 HashMap hints = new HashMap(); hints.put(EncodeHintType.CHARACTER_SET, "utf-8"); hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M);//设置二维码的容错等级 hints.put(EncodeHintType.MARGIN, 2);//边距 return new MultiFormatWriter().encode(contents, BarcodeFormat.QR_CODE, width, height, hints); } public BufferedImage toBufferedImage(BitMatrix matrix) { int width = matrix.getWidth(); int height = matrix.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, matrix.get(x, y) ? BLACK : WHITE); } } return image; } /** * 将生产的二维码写入图片文件 * @param file * @throws IOException */ public void writeToFile(File file) throws IOException, WriterException { BitMatrix matrix = CreatQRCode(); BufferedImage image = toBufferedImage(matrix); if (!ImageIO.write(image, format, file)) { throw new IOException("Could not write an image of format " + format + " to " + file); } } /** * 将生成的二维码以二进制数组的形式返回 */ public byte[] writeToBytes() throws WriterException, IOException { BitMatrix matrix = CreatQRCode(); byte[] bytes = null; // 这么写,完事后自动关闭流 try(ByteArrayOutputStream byteArray = new ByteArrayOutputStream()){ BufferedImage image = toBufferedImage(matrix); if (!ImageIO.write(image, format, byteArray)) { throw new IOException("faild to write an image to bytes"); } bytes = byteArray.toByteArray(); } return bytes; } ~~~