今天,写了一个二维码制作的工具类,在这里和大家分享一下。
需要在pom文件中添加jar包com.google.zxing core 3.2.1
java代码
package com.maque.boothero.common; import com.alibaba.druid.util.StringUtils; import com.google.zxing.BarcodeFormat; import com.google.zxing.EncodeHintType; import com.google.zxing.MultiFormatWriter; import com.google.zxing.common.BitMatrix; import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel; import javax.imageio.ImageIO; import java.awt.*; import java.awt.geom.RoundRectangle2D; import java.awt.image.BufferedImage; import java.io.*; import java.util.Hashtable; /** * @program: boot-hero * @description: 生成二维码工具类 * @author: maque * @create: 2018-07-19 18:01 */ public class QRCodeImageUtil { // 二维码尺寸 private static final int QRCODE_SIZE = 300; // 说明文本高度 private static final int HEIGHT_TEXT = 30; // LOGO宽度 private static final int WIDTH_LOGO = 110; // LOGO高度 private static final int HEIGHT_LOGO = 110; private static final String Encoding = "utf-8"; private static final String FORMAT_NAME = "JPG"; private static final int BLACK = 0xFF000000; private static final int WHITE = 0xFFFFFFFF; public static void main(String[] args) { String content = "http://www.baidu.com";//可以将此处的地址换成你的登录地址 String text = "百度一下就知道,百度一下就知道,百度一下就知道,百度一下就知道,百度一下就知道,"; try { FileInputStream is = new FileInputStream(new File("E:\\temp\\toPDF\\555.jpg")); ByteArrayOutputStream bytestream = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; int ch; while ((ch = is.read(buffer)) != -1) { bytestream.write(buffer,0,ch); } byte[] data = bytestream.toByteArray(); bytestream.close(); // byte[] imageBody = createQRCode("http://www.baidu.com"); // byte[] imageBody = createQRCodeWithText(content,text); // byte[] imageBody = createQRCodeWithLogo(content,data); byte[] imageBody = createQRCodeWithLogoAndText(content,text,data); String filename = DateUtil.getCurrentDateTimeToStr()+ ".jpg"; FileOutputStream os = new FileOutputStream(new File("E:\\temp\\toPDF\\"+filename)); os.write(imageBody); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } /** * * * @param content 二维码内容 * @return 二维码图片字节数组 */ public static byte[] createQRCode(String content){ if (StringUtils.isNumber(content)) { return null; } Hashtablehints = new Hashtable (); // ErrorCorrectionLevel.H 容错率:容错率越高,纠错等级越高,算法越复杂, // 解析软件识别出其内容的机率越大(你的logo就可以设置的更大)。 // 但是二维码所存储的内容也越少,可丢失的数据也就越多; /*L = ~7% correction L(0x01), M = ~15% correction M(0x00), Q = ~25% correction Q(0x03), H = ~30% correction H(0x02);*/ hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H); // 使用小写的编码,大写会出现]Q2\000026开头内容 hints.put(EncodeHintType.CHARACTER_SET, Encoding); //边缘空白 hints.put(EncodeHintType.MARGIN, 1); ByteArrayOutputStream output = new ByteArrayOutputStream(); try { BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE,QRCODE_SIZE,QRCODE_SIZE,hints); BufferedImage image = new BufferedImage(bitMatrix.getWidth(), bitMatrix.getHeight(), BufferedImage.TYPE_INT_RGB); for (int w = 0; w < image.getWidth(); w++ ) { for (int h = 0; h < image.getHeight(); h++ ) { //bitMatrix.get(w,h) 返回的是Boolean类型,true (w,h)此点为黑色,false(w,h)此点像素为白色 image.setRGB(w,h,bitMatrix.get(w,h) ? BLACK : WHITE); } } //将图片转换成byte数组 ImageIO.write(image,FORMAT_NAME,output); } catch (Exception e) { e.printStackTrace(); } return output.toByteArray(); } /** * 生成二维码(包含说明文本,不包含LOGO) * * @param content 二维码内容 * @param text 说明文本 * @return 二维码图片字节数组 */ public static byte[] createQRCodeWithText(String content,String text){ try { byte [] imageBody = createQRCode(content); if (!StringUtils.isNumber(text) ) { int num = QRCODE_SIZE / 26; int textNum = text.length(); if (textNum > num ) { String firstLine = text.substring(0,num); byte[] firstLineBody = insertText(imageBody,firstLine); String lastLine = text.substring(num,text.length()); byte[] lastLineBody = insertText(firstLineBody,lastLine); return lastLineBody; } else { byte[] lastLineBody = insertText(imageBody,text); return lastLineBody; } } return null; } catch (Exception e) { e.printStackTrace(); return null; } } /** * 向二维码中插入说明文 * * @param imageBody 二维码图片 * @param text 说明文 * @return 二维码图片字节数组 */ public static byte[] insertText(byte[] imageBody,String text){ try { ByteArrayInputStream bais = new ByteArrayInputStream(imageBody); BufferedImage image = ImageIO.read(bais); if (!StringUtils.isNumber(text) ) { int num = QRCODE_SIZE / 26; int textNum = text.length(); if (textNum > num) { String firstLine = text.substring(0,num); byte[] firstLineBody = insertText(imageBody,firstLine); String lastLine = text. substring(num,text.length()); byte[] lastLineBody = insertText(firstLineBody,lastLine); return lastLineBody; } } //创建一个新的图片底板。宽度不变,高度加上一个文本的高度。 BufferedImage outImage = new BufferedImage(image.getWidth(), image.getHeight() + HEIGHT_TEXT, BufferedImage.TYPE_INT_RGB); Graphics2D outg = outImage.createGraphics(); // 画二维码到新的面板 outg.drawImage(image, 0, 0, image.getWidth(), image.getHeight(), null); //将文本背景设置成白色。 for (int x = 0; x < image.getWidth(); x++) { for (int y = image.getHeight(); y < (outImage.getHeight()); y++) { outImage.setRGB(x, y, WHITE); } } // 画文字到新的面板 outg.setColor(Color.BLACK); outg.setFont(new Font("宋体", Font.BOLD, 25)); // 字体、字型、字号 25号字大约是26像素(包含字之间的空隙) int strWidth = outg.getFontMetrics().stringWidth(text); if (strWidth > QRCODE_SIZE) { // 画文字 向左对齐 outg.drawString(text, 0, image.getHeight() + (outImage.getHeight() - image.getHeight()) / 2 + 12); } else { // 画文字 居中 outg.drawString(text, QRCODE_SIZE / 2 - strWidth / 2, image.getHeight() + (outImage.getHeight() - image.getHeight()) / 2 + 12); } outg.dispose();//释放资源 ByteArrayOutputStream os = new ByteArrayOutputStream(); ImageIO.write(outImage,FORMAT_NAME,os); return os.toByteArray(); } catch (IOException e) { e.printStackTrace(); } return null; } /** * 生成二维码(内嵌LOGO,不包含说明文本) * * @param content 二维码内容 * @param logo 图片 * @return 二维码图片字节数组 */ public static byte[] createQRCodeWithLogo(String content, byte[] logo){ if (!StringUtils.isEmpty(content)) { byte [] imageBody = createQRCode(content); ByteArrayInputStream bais = null; try { bais = new ByteArrayInputStream(imageBody); BufferedImage source = ImageIO.read(bais); if (null == logo || logo.length== 0) { System.out.println("该图片不存在!"); return null; } bais = new ByteArrayInputStream(logo); Image src = ImageIO.read(bais); int width = src.getWidth(null); int height = src.getHeight(null); if (true) { //压缩LOGO if (width > WIDTH_LOGO) { width = WIDTH_LOGO; } if (height > HEIGHT_LOGO) { height = HEIGHT_LOGO; } Image image = src.getScaledInstance(width, height, Image.SCALE_SMOOTH); BufferedImage tag = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); Graphics g = tag.getGraphics(); g.drawImage(image, 0, 0, null); g.dispose(); src = image; } // 插入LOGO Graphics2D graph = source.createGraphics(); int x = (QRCODE_SIZE - width) / 2; int y = (QRCODE_SIZE - height) / 2; graph.drawImage(src, x, y, width, height, null); Shape shape = new RoundRectangle2D.Float(x, y, width, width, 6, 6); graph.setStroke(new BasicStroke(3f)); graph.draw(shape); graph.dispose(); ByteArrayOutputStream os = new ByteArrayOutputStream(); ImageIO.write(source,FORMAT_NAME,os); return os.toByteArray(); } catch (IOException e) { e.printStackTrace(); return null; } } return null; } /** * 生成二维码(内嵌LOGO,含说明文本) * * @param conten 二维码内容 * @param text 说明文 * @param logo 图片 * @return 二维码图片字节数组 */ public static byte[] createQRCodeWithLogoAndText(String content, String text,byte[] logo){ return insertText(createQRCodeWithLogo(content,logo),text); } }
运行结果:
欢迎大家使用