热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Java生成二维码(带logo文字)

1.引入包com.google.zxingcore

1. 引入包


com.google.zxingcore3.3.0


2. 工具类 

import cn.hutool.core.codec.Base64;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.qrcode.BufferedImageLuminanceSource;
import com.google.zxing.*;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.HybridBinarizer;
import com.google.zxing.qrcode.QRCodeWriter;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import com.pig4cloud.pigx.common.oss.service.OssTemplate;
import lombok.AllArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.*;
import java.util.List;public class QRCodeUtil {private static final int BLACK &#61; 0xFF000000;// 二维码颜色&#61;&#61;白色private static final int WHITE &#61; 0xFFFFFFFF;// 二维码图片格式&#61;&#61;jpg和png两种private static final List IMAGE_TYPE &#61; new ArrayList<>();static {IMAGE_TYPE.add("jpg");IMAGE_TYPE.add("png");}/*** zxing方式生成二维码* 注意&#xff1a;* 1,文本生成二维码的方法独立出来,返回image流的形式,可以输出到页面* 2,设置容错率为最高,一般容错率越高,图片越不清晰, 但是只有将容错率设置高一点才能兼容logo图片* 3,logo图片默认占二维码图片的20%,设置太大会导致无法解析** &#64;param content 二维码包含的内容&#xff0c;文本或网址* &#64;param path 生成的二维码图片存放位置* &#64;param size 生成的二维码图片尺寸 可以自定义或者默认&#xff08;250&#xff09;* &#64;param logoPath logo的存放位置*/public static boolean zxingCodeCreate(String content, String path, Integer size, String logoPath) {try {//图片类型String imageType &#61; "jpg";//获取二维码流的形式&#xff0c;写入到目录文件中BufferedImage image &#61; getBufferedImage(content, size, logoPath);//获得随机数Random random &#61; new Random();//生成二维码存放文件File file &#61; new File(path&#43;".jpg");if (!file.exists()) {file.mkdirs();}ImageIO.write(image, imageType, file);return true;} catch (IOException e) {e.printStackTrace();return false;}}/*** zxing方式生成二维码&#xff08;上传到minio&#xff09;* 注意&#xff1a;* 1,文本生成二维码的方法独立出来,返回image流的形式,可以输出到页面* 2,设置容错率为最高,一般容错率越高,图片越不清晰, 但是只有将容错率设置高一点才能兼容logo图片* 3,logo图片默认占二维码图片的20%,设置太大会导致无法解析** &#64;param content 二维码包含的内容&#xff0c;文本或网址* &#64;param size 生成的二维码图片尺寸 可以自定义或者默认&#xff08;250&#xff09;* &#64;param logoPath logo的存放位置*/public static InputStream codeCreateMinio(String content, Integer size, String logoPath) {//图片类型String imageType &#61; "jpg";//获取二维码流的形式&#xff0c;写入到目录文件中BufferedImage image &#61; getBufferedImage(content, size, logoPath);ByteArrayOutputStream os &#61; new ByteArrayOutputStream();try {ImageIO.write(image, imageType, os);InputStream input &#61; new ByteArrayInputStream(os.toByteArray());return input;} catch (IOException e) {e.printStackTrace();}return null;}/*** 二维码流的形式&#xff0c;包含文本内容** &#64;param content 二维码文本内容* &#64;param size 二维码尺寸* &#64;param logoPath logo的存放位置* &#64;return*/public static BufferedImage getBufferedImage(String content, Integer size, String logoPath) {if (size &#61;&#61; null || size <&#61; 0) {size &#61; 250;}BufferedImage image &#61; null;try {// 设置编码字符集Map hints &#61; new HashMap<>();//设置编码hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");//设置容错率最高hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M);hints.put(EncodeHintType.MARGIN, 1);// 1、生成二维码MultiFormatWriter multiFormatWriter &#61; new MultiFormatWriter();BitMatrix bitMatrix &#61; multiFormatWriter.encode(content, BarcodeFormat.QR_CODE, size, size, hints);// 2、获取二维码宽高int codeWidth &#61; bitMatrix.getWidth();int codeHeight &#61; bitMatrix.getHeight();// 3、将二维码放入缓冲流image &#61; new BufferedImage(codeWidth, codeHeight, BufferedImage.TYPE_INT_RGB);for (int i &#61; 0; i image.getWidth() * 2 / 10 ? (image.getWidth() * 2 / 10) : logo.getWidth(null);int heightLogo &#61; logo.getHeight(null) > image.getHeight() * 2 / 10 ? (image.getHeight() * 2 / 10) : logo.getHeight(null);int x &#61; (image.getWidth() - widthLogo) / 2;int y &#61; (image.getHeight() - heightLogo) / 2;// 开始绘制图片g.drawImage(logo, x, y, widthLogo, heightLogo, null);g.drawRoundRect(x, y, widthLogo, heightLogo, 15, 15);//边框宽度g.setStroke(new BasicStroke(2));//边框颜色g.setColor(Color.WHITE);g.drawRect(x, y, widthLogo, heightLogo);g.dispose();logo.flush();image.flush();}}} catch (WriterException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}return image;}/*** 给二维码图片添加Logo** &#64;param qrPic 二维码图片* &#64;param logoPic logo图片* &#64;param path 合成后的图片存储目录*/public static boolean zxingCodeCreate(File qrPic, File logoPic, String path) {try {String imageType &#61; path.substring(path.lastIndexOf(".") &#43; 1).toLowerCase();if (!IMAGE_TYPE.contains(imageType)) {return false;}if (!qrPic.isFile() && !logoPic.isFile()) {return false;}//读取二维码图片&#xff0c;并构建绘图对象BufferedImage image &#61; ImageIO.read(qrPic);Graphics2D g &#61; image.createGraphics();//读取Logo图片BufferedImage logo &#61; ImageIO.read(logoPic);//设置logo的大小,最多20%0int widthLogo &#61; logo.getWidth(null) > image.getWidth() * 2 / 10 ? (image.getWidth() * 2 / 10) : logo.getWidth(null);int heightLogo &#61; logo.getHeight(null) > image.getHeight() * 2 / 10 ? (image.getHeight() * 2 / 10) : logo.getHeight(null);// 计算图片放置位置&#xff0c;默认在中间int x &#61; (image.getWidth() - widthLogo) / 2;int y &#61; (image.getHeight() - heightLogo) / 2;// 开始绘制图片g.drawImage(logo, x, y, widthLogo, heightLogo, null);g.drawRoundRect(x, y, widthLogo, heightLogo, 15, 15);//边框宽度g.setStroke(new BasicStroke(2));//边框颜色g.setColor(Color.WHITE);g.drawRect(x, y, widthLogo, heightLogo);g.dispose();logo.flush();image.flush();File newFile &#61; new File(path);if (!newFile.exists()) {newFile.mkdirs();}ImageIO.write(image, imageType, newFile);return true;} catch (Exception e) {e.printStackTrace();return false;}}/*** 二维码的解析方法** &#64;param path 二维码图片目录* &#64;return*/public static Result zxingCodeAnalyze(String path) {try {MultiFormatReader formatReader &#61; new MultiFormatReader();File file &#61; new File(path);if (file.exists()) {BufferedImage image &#61; ImageIO.read(file);LuminanceSource source &#61; new BufferedImageLuminanceSource(image);Binarizer binarizer &#61; new HybridBinarizer(source);BinaryBitmap binaryBitmap &#61; new BinaryBitmap(binarizer);Map hints &#61; new HashMap();hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");Result result &#61; formatReader.decode(binaryBitmap, hints);return result;}} catch (IOException e) {e.printStackTrace();} catch (NotFoundException e) {e.printStackTrace();}return null;}/*** 二维码流的形式&#xff0c;包含文本内容** &#64;param content 二维码文本内容* &#64;param size 二维码尺寸* &#64;param logoPath logo的存放位置* &#64;return*/public static BufferedImage getBufferedImage8(String content, Integer size, String logoPath,List ptexts) {if (size &#61;&#61; null || size <&#61; 0) {size &#61; 250;}BufferedImage image &#61; null;try {// 设置编码字符集Map hints &#61; new HashMap<>();//设置编码hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");//设置容错率最高hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M);hints.put(EncodeHintType.MARGIN, 1);// 1、生成二维码MultiFormatWriter multiFormatWriter &#61; new MultiFormatWriter();BitMatrix bitMatrix &#61; multiFormatWriter.encode(content, BarcodeFormat.QR_CODE, size, size, hints);// 2、获取二维码宽高int codeWidth &#61; bitMatrix.getWidth();int codeHeight &#61; bitMatrix.getHeight();if(CollUtil.isNotEmpty(ptexts)){codeHeight&#61;codeHeight&#43;20*ptexts.size()&#43;10;}// 3、将二维码放入缓冲流image &#61; new BufferedImage(codeWidth, codeHeight, BufferedImage.TYPE_INT_RGB);for (int i &#61; 0; i image.getWidth() * 2 / 10 ? (image.getWidth() * 2 / 10) : logo.getWidth(null);int heightLogo &#61; logo.getHeight(null) > image.getHeight() * 2 / 10 ? (image.getHeight() * 2 / 10) : logo.getHeight(null);int x &#61; (image.getWidth() - widthLogo) / 2;int y &#61; (image.getHeight() - heightLogo) / 2;// 开始绘制图片g.drawImage(logo, x, y, widthLogo, heightLogo, null);g.drawRoundRect(x, y, widthLogo, heightLogo, 15, 15);//边框宽度g.setStroke(new BasicStroke(2));//边框颜色g.setColor(Color.WHITE);g.drawRect(x, y, widthLogo, heightLogo);g.dispose();logo.flush();image.flush();}}} catch (WriterException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}return image;}/*** 返回base64* */public static String crateQRCode(String content, Integer size, String logoPath,List ptexts) throws IOException {//输出流ByteArrayOutputStream stream &#61; new ByteArrayOutputStream();try {//图片类型String imageType &#61; "png";//获取二维码流的形式&#xff0c;写入到目录文件中BufferedImage image &#61; getBufferedImage8(content, size, logoPath,ptexts);ImageIO.write(image, imageType, stream);return Base64.encode(stream.toByteArray());} catch (IOException e) {e.printStackTrace();}return null;}/*** zxing方式生成二维码* 注意&#xff1a;* 1,文本生成二维码的方法独立出来,返回image流的形式,可以输出到页面* 2,设置容错率为最高,一般容错率越高,图片越不清晰, 但是只有将容错率设置高一点才能兼容logo图片* 3,logo图片默认占二维码图片的20%,设置太大会导致无法解析** &#64;param content 二维码包含的内容&#xff0c;文本或网址* &#64;param path 生成的二维码图片存放位置* &#64;param size 生成的二维码图片尺寸 可以自定义或者默认&#xff08;250&#xff09;* &#64;param logoPath logo的存放位置*/public static boolean zxingCodeCreate8(String content, String path, Integer size, String logoPath) {try {//图片类型String imageType &#61; "png";//获取二维码流的形式&#xff0c;写入到目录文件中List ptexts &#61; new ArrayList<>();ptexts.add("设备id: NO20220309-00909");ptexts.add("设备名称: 松下打印机哈哈哈哈哈哈哈哈就好哈哈哈哈哈哈哈哈哈哈哈哈gh哈哈哈哈哈哈哈哈哈哈103室");ptexts.add("设备名称: 松下打印机哈哈哈哈哈哈哈哈就好哈哈哈哈哈哈哈哈哈哈哈哈gh哈哈哈哈哈哈哈哈哈哈103室");ptexts.add("设备名称: 松下打印机哈哈哈哈哈哈哈哈就好哈哈哈哈哈哈哈哈哈哈哈哈gh哈哈哈哈哈哈哈哈哈哈103室");ptexts.add("设备名称: 松下打印机哈哈哈哈哈哈哈哈就好哈哈哈哈哈哈哈哈哈哈哈哈gh哈哈哈哈哈哈哈哈哈哈103室");BufferedImage image &#61; getBufferedImage8(content, size, logoPath,ptexts);//获得随机数Random random &#61; new Random();//生成二维码存放文件File file &#61; new File(path&#43;".png");if (!file.exists()) {file.mkdirs();}ImageIO.write(image, imageType, file);return true;} catch (IOException e) {e.printStackTrace();return false;}}
// public static void main(String[] args) {
// String path&#61;"/Users/liangyating/IdeaProjects/cltech-dmin/cltech/cltech-biz/src/main/resources/file/";
// String url &#61; "https://test.chaolingroup.com/#/device/upkeep/type";
// //生成二维码
// boolean qc&#61; QRCodeUtil.zxingCodeCreate8(url,path&#43;"1",300,null);
//
//
// }}

3. 效果如下

 


推荐阅读
  • 个人学习使用:谨慎参考1Client类importcom.thoughtworks.gauge.Step;importcom.thoughtworks.gauge.T ... [详细]
  • Java太阳系小游戏分析和源码详解
    本文介绍了一个基于Java的太阳系小游戏的分析和源码详解。通过对面向对象的知识的学习和实践,作者实现了太阳系各行星绕太阳转的效果。文章详细介绍了游戏的设计思路和源码结构,包括工具类、常量、图片加载、面板等。通过这个小游戏的制作,读者可以巩固和应用所学的知识,如类的继承、方法的重载与重写、多态和封装等。 ... [详细]
  • 本文介绍了一个Java猜拳小游戏的代码,通过使用Scanner类获取用户输入的拳的数字,并随机生成计算机的拳,然后判断胜负。该游戏可以选择剪刀、石头、布三种拳,通过比较两者的拳来决定胜负。 ... [详细]
  • Java序列化对象传给PHP的方法及原理解析
    本文介绍了Java序列化对象传给PHP的方法及原理,包括Java对象传递的方式、序列化的方式、PHP中的序列化用法介绍、Java是否能反序列化PHP的数据、Java序列化的原理以及解决Java序列化中的问题。同时还解释了序列化的概念和作用,以及代码执行序列化所需要的权限。最后指出,序列化会将对象实例的所有字段都进行序列化,使得数据能够被表示为实例的序列化数据,但只有能够解释该格式的代码才能够确定数据的内容。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • Spring特性实现接口多类的动态调用详解
    本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • 本文详细介绍了Java中vector的使用方法和相关知识,包括vector类的功能、构造方法和使用注意事项。通过使用vector类,可以方便地实现动态数组的功能,并且可以随意插入不同类型的对象,进行查找、插入和删除操作。这篇文章对于需要频繁进行查找、插入和删除操作的情况下,使用vector类是一个很好的选择。 ... [详细]
  • r2dbc配置多数据源
    R2dbc配置多数据源问题根据官网配置r2dbc连接mysql多数据源所遇到的问题pom配置可以参考官网,不过我这样配置会报错我并没有这样配置将以下内容添加到pom.xml文件d ... [详细]
  • Spring学习(4):Spring管理对象之间的关联关系
    本文是关于Spring学习的第四篇文章,讲述了Spring框架中管理对象之间的关联关系。文章介绍了MessageService类和MessagePrinter类的实现,并解释了它们之间的关联关系。通过学习本文,读者可以了解Spring框架中对象之间的关联关系的概念和实现方式。 ... [详细]
  • 先看官方文档TheJavaTutorialshavebeenwrittenforJDK8.Examplesandpracticesdescribedinthispagedontta ... [详细]
  • 本文介绍了Swing组件的用法,重点讲解了图标接口的定义和创建方法。图标接口用来将图标与各种组件相关联,可以是简单的绘画或使用磁盘上的GIF格式图像。文章详细介绍了图标接口的属性和绘制方法,并给出了一个菱形图标的实现示例。该示例可以配置图标的尺寸、颜色和填充状态。 ... [详细]
  • Android工程师面试准备及设计模式使用场景
    本文介绍了Android工程师面试准备的经验,包括面试流程和重点准备内容。同时,还介绍了建造者模式的使用场景,以及在Android开发中的具体应用。 ... [详细]
  • 纠正网上的错误:自定义一个类叫java.lang.System/String的方法
    本文纠正了网上关于自定义一个类叫java.lang.System/String的错误答案,并详细解释了为什么这种方法是错误的。作者指出,虽然双亲委托机制确实可以阻止自定义的System类被加载,但通过自定义一个特殊的类加载器,可以绕过双亲委托机制,达到自定义System类的目的。作者呼吁读者对网上的内容持怀疑态度,并带着问题来阅读文章。 ... [详细]
  • ***byte(字节)根据长度转成kb(千字节)和mb(兆字节)**parambytes*return*publicstaticStringbytes2kb(longbytes){ ... [详细]
author-avatar
墨镜空间新
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有