java生成二维码图片(有logo),并在图片下方附文字

2023-10-26

  • logo配置类
/**
 * Created by Amber Wang on 2017/11/27 17:25.
 */

import java.awt.*;

public class LogoConfig {
    // logo默认边框颜色
    public static final Color DEFAULT_BORDERCOLOR = Color.WHITE;
    // logo默认边框宽度
    public static final int DEFAULT_BORDER = 2;
    // logo大小默认为二维码照片的1/6
    public static final int DEFAULT_LOGOPART = 6;

    private final int border = DEFAULT_BORDER;
    private final Color borderColor;
    private final int logoPart;

    /**
     * Creates a default config with on color {@link #BLACK} and off color
     * {@link #WHITE}, generating normal black-on-white barcodes.
     */
    public LogoConfig() {
        this(DEFAULT_BORDERCOLOR, DEFAULT_LOGOPART);
    }

    public LogoConfig(Color borderColor, int logoPart) {
        this.borderColor = borderColor;
        this.logoPart = logoPart;
    }

    public Color getBorderColor() {
        return borderColor;
    }

    public int getBorder() {
        return border;
    }

    public int getLogoPart() {
        return logoPart;
    }
}
  • MatrixToImage类
/**
 * Created by Amber Wang on 2017/11/27 17:24.
 */

import com.google.zxing.common.BitMatrix;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;

public final class MatrixToImageWriter {

    private static final int BLACK = 0xFF000000;
    private static final int WHITE = 0xFFFFFFFF;

    private MatrixToImageWriter() {
    }

    public static 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 - 50; y++) {
                image.setRGB(x, y, matrix.get(x, y + 50) ? BLACK : WHITE);
            }
        }
        return image;
    }


    public static BufferedImage writeToFile(BitMatrix matrix, String format)
            throws IOException {
        BufferedImage image = toBufferedImage(matrix);
        return image;
    }


    public static void writeToStream(BitMatrix matrix, String format, OutputStream stream)
            throws IOException {
        BufferedImage image = toBufferedImage(matrix);
        if (!ImageIO.write(image, format, stream)) {
            throw new IOException("Could not write an image of format " + format);
        }
    }

}
  • 给二维码图片添加Logo
/**
     * 给二维码图片添加Logo
     *
     * @param barCodeImage
     * @param logoPic
     */
    public static BufferedImage addLogo_QRCode(BufferedImage barCodeImage, File logoPic, LogoConfig logoConfig) {
        try {
            if (!logoPic.isFile()) {
                System.out.print("file not find !");
                throw new IOException("file not find !");
            }

            /**
             * 读取二维码图片,并构建绘图对象
             */
            Graphics2D g = barCodeImage.createGraphics();

            /**
             * 读取Logo图片
             */
            BufferedImage logo = ImageIO.read(logoPic);

            int widthLogo = barCodeImage.getWidth() / logoConfig.getLogoPart();
            int heightLogo = barCodeImage.getWidth() / logoConfig.getLogoPart(); //保持二维码是正方形的

            // 计算图片放置位置
            int x = (barCodeImage.getWidth() - widthLogo) / 2;
            int y = (barCodeImage.getHeight() - heightLogo) / 2 - 50;


            //开始绘制图片
            g.drawImage(logo, x, y, widthLogo, heightLogo, null);
            g.drawRoundRect(x, y, widthLogo, heightLogo, 10, 10);
            g.setStroke(new BasicStroke(logoConfig.getBorder()));
            g.setColor(logoConfig.getBorderColor());
            g.drawRect(x, y, widthLogo, heightLogo);

            g.dispose();
            return barCodeImage;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
  • 给二维码图片下方附说明文字

    /**
     * @param pressText 文字
     * @param newImg    带文字的图片
     * @param image     需要添加文字的图片
     * @param fontStyle
     * @param color
     * @param fontSize
     * @param width
     * @param height
     * @为图片添加文字
     */
    public static void pressText(String pressText, String newImg, BufferedImage image, int fontStyle, Color color, int fontSize, int width, int height) {

        //计算文字开始的位置
        //x开始的位置:(图片宽度-字体大小*字的个数)/2
        int startX = (width - (fontSize * pressText.length())) - 10;
        //y开始的位置:图片高度-(图片高度-图片宽度)/2
        int startY = height - (height - width) / 2 - 30;

        System.out.println("startX: " + startX);
        System.out.println("startY: " + startY);
        System.out.println("height: " + height);
        System.out.println("width: " + width);
        System.out.println("fontSize: " + fontSize);
        System.out.println("pressText.length(): " + pressText.length());

        try {
//            File file = new File(targetImg);
//            Image src = ImageIO.read(file);
            int imageW = image.getWidth();
            int imageH = image.getHeight();
//            BufferedImage image = new BufferedImage(imageW, imageH, BufferedImage.TYPE_INT_RGB);
            Graphics g = image.createGraphics();
            g.drawImage(image, 0, 0, imageW, imageH, null);
            g.setColor(color);
            g.setFont(new Font("粗体", Font.BOLD, 30));
            g.drawString(pressText, startX, startY);
            g.drawString("广 告 牌 0 1", startX + 30, startY + 30);
            g.dispose();

            FileOutputStream out = new FileOutputStream(newImg);
            ImageIO.write(image, "JPEG", out);
            JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
            encoder.encode(image);
            out.close();
            System.out.println("image press success");
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println(e);
        }
    }
  • main测试
//二维码表示的内容
    private static String content = "http://www.changxingnanjing.com?qr_code=01900302|773f3c8f872bf34cc3fe97022720330e";

    //存放logo的文件夹
    private static String path = "E:/QRCodeImage";

    public static void main(String args[]) {
        try {
            MultiFormatWriter multiFormatWriter = new MultiFormatWriter();

            @SuppressWarnings("rawtypes")
            Map hints = new HashMap();

            //设置UTF-8, 防止中文乱码
            hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
            //设置二维码四周白色区域的大小
            hints.put(EncodeHintType.MARGIN, 2);
            //设置二维码的容错性
            hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);

            //width:图片完整的宽;height:图片完整的高
            //因为要在二维码下方附上文字,所以把图片设置为长方形(高大于宽)
            int width = 352;//352
            int height = 500;//612

            //画二维码,记得调用multiFormatWriter.encode()时最后要带上hints参数,不然上面设置无效
            BitMatrix bitMatrix = multiFormatWriter.encode(content, BarcodeFormat.QR_CODE, width, height, hints);

            //qrcFile用来存放生成的二维码图片(无logo,无文字)
            File logoFile = new File(path, "logo.jpg");

            //开始画二维码
            BufferedImage barCodeImage = MatrixToImageWriter.writeToFile(bitMatrix, "jpg");

            //在二维码中加入图片
            LogoConfig logoConfig = new LogoConfig(); //LogoConfig中设置Logo的属性
            BufferedImage image = addLogo_QRCode(barCodeImage, logoFile, logoConfig);

            int font = 18; //字体大小
            int fontStyle = 1; //字体风格

            //用来存放带有logo+文字的二维码图片
            String newImageWithText = path + "/imageWithText.jpg";
            //附加在图片上的文字信息
            String text = "0 1 1 0 9 0 2 9";

            //在二维码下方添加文字(文字居中)
            pressText(text, newImageWithText, image, fontStyle, Color.black, font, width, height);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
  • 下附二维码样式

这里写图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

java生成二维码图片(有logo),并在图片下方附文字 的相关文章

  • 服务器盘符名称修改,linux下powerpath对盘与更改盘符名的教程

    PowerPath 软件在服务器上运行并管理服务器和存储系统中的虚拟磁盘之间的路径 如果一条路径出现故障 它可以将I O 转发到有效路径中 并提供负载平衡来平均分配各条路径中的I O 负载 另外这里的路径由HBA 硬件和驱动程序 光纤 两个
  • docker web mysql_在 Docker 中完整部署 Web 应用

    原标题 在 Docker 中完整部署 Web 应用 一个完整的 Web 应用包含前端页面 数据库 后台逻辑等 按照一般流程去构建需要配置 Nginx MySQL 以及后台服务器 运维涉及到的部分十分复杂 而 Docker 可以将这些东西 数
  • STM8 学习笔记13:PWM

    PWM Gitee 空间跳转 https gitee com galoc stm8 git 1 概述 PWM也叫脉冲宽度调制 是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术 频率 周期 占空比 1 1 PWM 频率 是指在
  • Java常用类System类、Math、BigInteger 和 BigDecimal

    1 System类 public void test1 String javaVersion System getProperty java version System out println java的version javaVersi
  • Windows磁盘管理中的压缩卷操作

    基本磁盘 主分区在压缩卷操作后为黑色的未分配 逻辑分区在压缩卷操作后为绿色的可用空间 动态磁盘 简单卷在压缩卷操作后为黑色的未分配
  • Figma怎么汉化?这个Figma 汉化插件早知道就好了!

    Figma官方目前没有中文版 可能与早期的封禁大疆事件和面向非洲地区扩张策略有关 但是可以使用第三方汉化插件来获得中文版本的Figma Figma cool是一个提供汉化插件的网站 支持多个平台 另外 还有一款名为即时设计的中文设计工具 提
  • java.lang.IllegalArgumentException 异常报错完美解决

    目录 修改JDK使用版本 修改开发工具idea配置 eclipse的直接跳过这个看下面 修改开发工具eclipse配置 学习spring依赖注入的时候碰到这个坑 折腾了许久 记录一下以防其他小伙伴入坑 该异常主要原因是因为JDK与Sprin
  • Lisp-Stat 翻译 —— 第四章 其它Lisp特性

    2019独角兽企业重金招聘Python工程师标准 gt gt gt 第四章 其它Lisp特性 上一章介绍了Lisp编程的基础 在那章里重点展示了对编写Lisp函数有用的编程技术 为了最高效地使用这些技术 知道Lisp和Lisp Stat提供
  • 智能指针之shared_ptr初始化,引用计数,常用操作和自定义删除器等等03

    一 share ptr 1 share ptr基础 1 共享所有权 不是被一个shared ptr拥有 而是被多个shared ptr之间相互协作 shared有额外开销 2 工作原理 利用引用计数的方法管理一片内存 每增加一个shared
  • C++ 一些知识点

    https www nowcoder com profile 7838045 myFollowings detail 3445247 链接 https www nowcoder com questionTerminal 087006d1e4
  • Red Hat Linux 7.5的安装及修改密码【详细】

    一 如何安装Red Hat Linux 7 5 详细 1 打开安装好的VMware 点击主页上的 创建新的虚拟机 选择 自定义 后 点击 下一步 2 选择虚拟机硬盘兼容性 我们选择Wordstation 14 x 3 选择稍后安装操作系统
  • -bash: ./mysqld: 没有那个文件或目录解决方法

    MySQL问题 bash mysqld 没有那个文件或目录 mysql安装路径 usr local mysql bin vi etc profile 添加环境变量 export PATH PATH usr local mysql bin 重
  • 营销活动:提升小程序的用户活跃度的关键

    在现今竞争激烈的商业环境中 小程序已成为企业私域营销的重要工具之一 然而 拥有一个小程序并不足以保证用户的活跃度 营销活动作为推动用户参与的有效方式 对于提升小程序的用户活跃度起着至关重要的作用 本文将深入探讨营销活动在提升小程序用户活跃度
  • Swagger的用法

    Swagger的用法 1 yml配置文件中引入依赖
  • C++ 内存管理

    C 内存管理 关于析构函数 1 when the desconstructor will be called 具体地说如果出现以下几种情况 程序就会执行析构函数 如果在一个函数中定义了一个对象 它是自动局部对象 当这个函数被调用结束时 对象
  • 静态代码块

    在Java类中 使用static关键字修饰的代码块称为静态代码块 当类被加载的时候 静态代码块就会被执行 由于类只会加载一次 所以静态代码块只会执行一次 在程序当中 使用静态代码块对类的成员变量进行初始化 package qmfx2 pub
  • FastAPI 使用 WebSocket创建实时应用程序

    超文本传输协议 或 HTTP 是当今互联网上最常用的协议之一 它允许客户端获取资源 例如 HTML 页面和图像 客户端 通常是浏览器 向服务器请求资源 图像 CSS 文件等 服务器响应请求的数据 它是一个严格的单向协议 服务器只会在客户端请
  • conda install 和 pip install 在ubuntu上的区别

    conda install 和 pip install 在ubuntu上的区别 pip和conda 看了很多博主的解释 已经说的很清楚了 pip pip installs packages 和conda都是包管理系统 pip最常用于安装在p
  • Merkle树

    白皮书引入 Merkel树是一种数据结构 图1 1 比特币白皮书插图 生成一个Merkel树 图1 2 来自维基百科插图 分析 自下而上 我们有四个文件 比特币系统的话就是交易 这个数据结构可以用在各种方面 L1 L2 L3 L4 四个文件

随机推荐

  • QT学习-数据类型转换

    文章目录 前言 一 num转QString 二 数据输出格式 三 QString拆分到QStringList 1 去除空格拆分 2 按固定长度拆分 四 QStringList转QByteArray HEX 五 uint8 t与QByteAr
  • java关键字const_java 关键字详解

    一 关键字总览 访问控制 private protected public 类 方法和变量修饰符 abstract class extends final implements interface native new static str
  • 用JAVA语言写一个计算员工月工资的程序

    一 任务需求 某公司分为多个部门 每个部门有一个经理和多个员工 每个员工根据职称发基本工资 员工的工资由基本工资 日加班工资 日缺勤工资等组成 具体需求如下所示 员工的基本信息 包括部门 职务 职称以及工资记录等信息 能记录员工的每一个职称
  • 过压保护芯片,IC电路方案集合

    随着快充适配器 QC3 0充电器 PD充电器的诞生 改变了原先USB的5V充电 增加了9V 12V的充电电压 甚至PD充电器20V也是很常见了 9V 12V 20V高电压的应用产生 虽然说9V 12V 20V的高压输出 不会被误触发 但是消
  • R-FCN+ResNet-50用自己的数据集训练模型(python版本)

    说明 本文假设你已经做好数据集 格式和VOC2007一致 并且Linux系统已经配置好caffe所需环境 博客里教程很多 下面是训练的一些修改 py R FCN源码下载地址 https github com Orpine py R FCN
  • react+antd+table实现表格数据,从头到尾循环、自动分页、滚动展示

    ts写法 分页是20 滚动过程中自动分页调接口返回数据 class Demo extends React Component
  • python调用resnet模型 对人脸图片进行特征提取,提取全连接层特征向量

    resnet feature extraction import os os chdir root caffe master examples import numpy as np import matplotlib pyplot as p
  • 汇编语言----mul指令

    mul指令 把操作数与AX相乘 最后存放在AX中 例子 mov ax 4 mov bx 5 mul bx ax 20
  • 动态设置src路径

    img class sidebar logo data return logo require assets dt logo png 如上动态设置图片的路径需要使用require 不然只能写上固定路径如下 img src assets dt
  • 排行榜|当 DB-Engines 遇见墨天轮国产数据库排行

    提到数据库排名 此时脑海里浮现出的是什么 是 DB Engines 还是墨天轮数据库排行 两者间有什么区别 下面来聊一下业内这两个知名数据库排名平台 本篇文章约有 3000 字 预计阅读时间 7 分钟 如阅读时间有限 请直接阅读文章末尾的对
  • 软件测试/测试开发丨容器编排K8S 下部署分布式UI自动化解决方案

    本文作者为霍格沃兹测试开发学社特约讲师乔巴 K8S目前是业界容器编排领域的事实标准 是几乎所有云原生架构的首选 目前随着云原生架构越来越流行 测试开发人员需要掌握K8S技术栈已经成为越来越迫切的需求 Kubernetes 开源于 2014
  • 敏捷开发-如何理解spring x

    2021年 不断思考一年 从领导风格转变让自己有点不适应 但是一直让自己谦卑心去学习每个人身上特长东西 接触过很多管理者 但是身上特点不足够明显的领导 我觉得不适合这个岗位 所以更多的调整心态去适应 找到每一个天 每个月 每一年战略目标自己
  • vc的编译过程

    对VC 工程编译过程的梳理 VC 的项目和解决方案文件解读 无非就是利用这些信息进行一个软件的编译 这些文件里面是存放的项目的配置和工程的组织 类似于makefile文件 但是只有VC 6 0的时候可以导出makefile文件 VC6的pr
  • python3 [爬虫入门实战]爬虫之scrapy爬取中国医学人才网

    自己第一次试着用scrapy进行爬取网页 总共爬下9240条数据 也就两分钟不到 400多页吧 用的比较简单 但是爬取成功后感觉成就感满满的 来张爬取结果图 爬取字段 hospitalName hospitalDesc hospitalSi
  • 【满分】【华为OD机试真题2023B卷 JS】乱序整数序列两数之和绝对值最小

    华为OD2023 B卷 机试题库全覆盖 刷题指南点这里 乱序整数序列两数之和绝对值最小 知识点排序数组 时间限制 1s 空间限制 256MB 限定语言 不限 题目描述 给定一个随机的整数 可能存在正整数和负整数 数组 nums 请你在该数组
  • X11协议基础与实践

    X11协议基础与实践 概念 X11 X Window System 是一种位图显示的视窗系统 X表示X协议 11是协议版本号 X 协议主要由 X server 和 X client 组成 l X server 管理主机上与显示相关的硬件设置
  • 对角线遍历

    param number matrix return number var findDiagonalOrder function matrix if matrix null matrix length 0 return let m matr
  • “40道高频区块链面试题”——我的一些看法

    最近看到了一篇文章如下 超强攻略 40道高频区块链面试题大放送 年底跳槽看过来 地址我也贴出来吧 https mp weixin qq com s 3Fa2XG4R11QDfMSAaBCngw 哦 CSDN的地址也出来了 https blo
  • vscode好用的前端插件和快捷键

    用到好用的vscode插件 总结一下 文章目录 一 常用主题 1 Material Theme主题 2 Community Material Theme主题 3 vscode icons 二 基础插件 1 Code Spell checke
  • java生成二维码图片(有logo),并在图片下方附文字

    logo配置类 Created by Amber Wang on 2017 11 27 17 25 import java awt public class LogoConfig logo默认边框颜色 public static final