用 zxing 生成带 logo 的二维码

本贴最后更新于 3374 天前,其中的信息可能已经时过境迁

给大家分享一个用zxing生成二维码的程序,话不多说,先看下效果

代码看下面!

import org.junit.Test;

/**
 * @author niuhaipeng
 *
 * @date 2015年12月24日
 */
public class QrCodeGeneratorTest {

    @Test
    public void testGenerateQrCode() {
        QrCodeGenerator generator = new QrCodeGenerator();
        String text = "http://niuhp.com";
        String targetPath = "d:/temp/niuhp/t1.jpg";
        String logoPath = "d:/temp/niuhp/niuhp.jpg";
        generator.generateQrCode(text, targetPath, logoPath);
    }

}

 

 

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.EnumMap;
import java.util.Map;

import javax.imageio.ImageIO;

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 com.niuhp.toolbox.logadapter.LogX;

/**
 * @author niuhaipeng
 *
 * @date 2015年12月20日
 */
public class QrCodeGenerator {
    private static final Color defaultBackgroundColor = new Color(192, 192, 192);
    private static final Color defaultForegroundColor = new Color(0, 128, 0);
    private static final Color defaultLogoBoundColor = new Color(0, 0, 255);
    private int background = defaultBackgroundColor.getRGB();
    private int foreground = defaultForegroundColor.getRGB();
    private String format = "jpg";
    private int width = 300;
    private int height = 300;
    private double logoRatio = 0.2;
    private Color logoBoundColor = defaultLogoBoundColor;

    public void generateQrCode(String text, String qrCodePath) {
        generateQrCode(text, qrCodePath, null);
    }

    public void generateQrCode(String text, String qrCodePath, String qrLogoPath) {
        int index = qrCodePath.lastIndexOf('.');
        if (index != -1) {
            format = qrCodePath.substring(index + 1);
        }
        Map<EncodeHintType, Object> hints = new EnumMap<EncodeHintType, Object>(EncodeHintType.class);
        hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
        // 二维码边界空白大小 1,2,3,4 (4为默认,最大)
        hints.put(EncodeHintType.MARGIN, 1);

        MultiFormatWriter multiFormatWriter = new MultiFormatWriter();

        try {
            BitMatrix bitMatrix = multiFormatWriter.encode(text, BarcodeFormat.QR_CODE, width, height, hints);
            BufferedImage image = toBufferedImage(bitMatrix);
            if (qrLogoPath != null) {
                File qrLogoFile = new File(qrLogoPath);
                image = addLogoToQrCode(image, qrLogoFile);
            }
            File qrCodeFile = new File(qrCodePath);
            ImageIO.write(image, format, qrCodeFile);
        } catch (Exception e) {
            LogX.getLogX(QrCodeGenerator.class).error(String.format("generateQrCode to %s error", qrCodePath), e);
        }
    }

    private BufferedImage addLogoToQrCode(BufferedImage qrImg, File qrLogoFile) {
        if (qrLogoFile == null || !qrLogoFile.exists() || !qrLogoFile.isFile()) {
            return qrImg;
        }
        try {
            Graphics2D g = qrImg.createGraphics();
            BufferedImage logoImg = ImageIO.read(qrLogoFile);
            int qrWidth = qrImg.getWidth();
            int qrHeight = qrImg.getHeight();
            int logoWidth = (int) (qrWidth * logoRatio);
            int logoHeight = (int) (qrHeight * logoRatio);
            int x = (qrWidth - logoWidth) / 2;
            int y = (qrHeight - logoHeight) / 2;
            g.drawImage(logoImg, x, y, logoWidth, logoHeight, null);
            g.drawRoundRect(x, y, logoWidth, logoHeight, 15, 15);
            // logo边框大小
            g.setStroke(new BasicStroke(1));
            g.setColor(logoBoundColor);
            g.drawRect(x, y, logoWidth, logoHeight);
            g.dispose();
            logoImg.flush();
            qrImg.flush();
        } catch (IOException e) {
            LogX.getLogX(QrCodeGenerator.class).error(
                    String.format("add logo %s to qr image error", qrLogoFile.getAbsolutePath()), e);
        }
        return qrImg;
    }

    private 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) ? foreground : background);
            }
        }
        return image;
    }

    public int getBackground() {
        return background;
    }

    public void setBackground(int background) {
        this.background = background;
    }

    public int getForeground() {
        return foreground;
    }

    public void setForeground(int foreground) {
        this.foreground = foreground;
    }

    public String getFormat() {
        return format;
    }

    public void setFormat(String format) {
        this.format = format;
    }

    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 double getLogoRatio() {
        return logoRatio;
    }

    public void setLogoRatio(double logoRatio) {
        this.logoRatio = logoRatio;
    }

    public Color getLogoBoundColor() {
        return logoBoundColor;
    }

    public void setLogoBoundColor(Color logoBoundColor) {
        this.logoBoundColor = logoBoundColor;
    }

 

maven依赖如下

        <dependency>
            <groupId>com.google.zxing</groupId>
            <artifactId>core</artifactId>
            <version>3.2.0</version>
        </dependency>

 

本文代码均可以从github下载地址 https://github.com/niuhp/toolbox

 

 

 

  • Java

    Java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的。Java 技术具有卓越的通用性、高效性、平台移植性和安全性。

    3194 引用 • 8214 回帖
  • zxing
    5 引用 • 3 回帖
  • 二维码
    9 引用 • 22 回帖
  • Logo
    8 引用 • 125 回帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...

推荐标签 标签

  • Gitea

    Gitea 是一个开源社区驱动的轻量级代码托管解决方案,后端采用 Go 编写,采用 MIT 许可证。

    5 引用 • 16 回帖 • 1 关注
  • iOS

    iOS 是由苹果公司开发的移动操作系统,最早于 2007 年 1 月 9 日的 Macworld 大会上公布这个系统,最初是设计给 iPhone 使用的,后来陆续套用到 iPod touch、iPad 以及 Apple TV 等产品上。iOS 与苹果的 Mac OS X 操作系统一样,属于类 Unix 的商业操作系统。

    87 引用 • 139 回帖
  • WebClipper

    Web Clipper 是一款浏览器剪藏扩展,它可以帮助你把网页内容剪藏到本地。

    3 引用 • 9 回帖 • 6 关注
  • sts
    2 引用 • 2 回帖 • 224 关注
  • React

    React 是 Facebook 开源的一个用于构建 UI 的 JavaScript 库。

    192 引用 • 291 回帖 • 382 关注
  • Latke

    Latke 是一款以 JSON 为主的 Java Web 框架。

    71 引用 • 535 回帖 • 819 关注
  • Spark

    Spark 是 UC Berkeley AMP lab 所开源的类 Hadoop MapReduce 的通用并行框架。Spark 拥有 Hadoop MapReduce 所具有的优点;但不同于 MapReduce 的是 Job 中间输出结果可以保存在内存中,从而不再需要读写 HDFS,因此 Spark 能更好地适用于数据挖掘与机器学习等需要迭代的 MapReduce 的算法。

    74 引用 • 46 回帖 • 568 关注
  • 钉钉

    钉钉,专为中国企业打造的免费沟通协同多端平台, 阿里巴巴出品。

    15 引用 • 67 回帖 • 297 关注
  • Bug

    Bug 本意是指臭虫、缺陷、损坏、犯贫、窃听器、小虫等。现在人们把在程序中一些缺陷或问题统称为 bug(漏洞)。

    76 引用 • 1742 回帖
  • BAE

    百度应用引擎(Baidu App Engine)提供了 PHP、Java、Python 的执行环境,以及云存储、消息服务、云数据库等全面的云服务。它可以让开发者实现自动地部署和管理应用,并且提供动态扩容和负载均衡的运行环境,让开发者不用考虑高成本的运维工作,只需专注于业务逻辑,大大降低了开发者学习和迁移的成本。

    19 引用 • 75 回帖 • 662 关注
  • Outlook
    1 引用 • 5 回帖 • 3 关注
  • Ngui

    Ngui 是一个 GUI 的排版显示引擎和跨平台的 GUI 应用程序开发框架,基于
    Node.js / OpenGL。目标是在此基础上开发 GUI 应用程序可拥有开发 WEB 应用般简单与速度同时兼顾 Native 应用程序的性能与体验。

    7 引用 • 9 回帖 • 396 关注
  • Netty

    Netty 是一个基于 NIO 的客户端-服务器编程框架,使用 Netty 可以让你快速、简单地开发出一个可维护、高性能的网络应用,例如实现了某种协议的客户、服务端应用。

    49 引用 • 33 回帖 • 32 关注
  • 创业

    你比 99% 的人都优秀么?

    82 引用 • 1395 回帖 • 4 关注
  • OpenCV
    15 引用 • 36 回帖
  • gRpc
    11 引用 • 9 回帖 • 88 关注
  • 印象笔记
    3 引用 • 16 回帖 • 1 关注
  • Shell

    Shell 脚本与 Windows/Dos 下的批处理相似,也就是用各类命令预先放入到一个文件中,方便一次性执行的一个程序文件,主要是方便管理员进行设置或者管理用的。但是它比 Windows 下的批处理更强大,比用其他编程程序编辑的程序效率更高,因为它使用了 Linux/Unix 下的命令。

    124 引用 • 74 回帖 • 2 关注
  • 国际化

    i18n(其来源是英文单词 internationalization 的首末字符 i 和 n,18 为中间的字符数)是“国际化”的简称。对程序来说,国际化是指在不修改代码的情况下,能根据不同语言及地区显示相应的界面。

    8 引用 • 26 回帖
  • Eclipse

    Eclipse 是一个开放源代码的、基于 Java 的可扩展开发平台。就其本身而言,它只是一个框架和一组服务,用于通过插件组件构建开发环境。

    76 引用 • 258 回帖 • 631 关注
  • 学习

    “梦想从学习开始,事业从实践起步” —— 习近平

    172 引用 • 515 回帖
  • 大数据

    大数据(big data)是指无法在一定时间范围内用常规软件工具进行捕捉、管理和处理的数据集合,是需要新处理模式才能具有更强的决策力、洞察发现力和流程优化能力的海量、高增长率和多样化的信息资产。

    93 引用 • 113 回帖
  • PostgreSQL

    PostgreSQL 是一款功能强大的企业级数据库系统,在 BSD 开源许可证下发布。

    22 引用 • 22 回帖 • 3 关注
  • RIP

    愿逝者安息!

    8 引用 • 92 回帖 • 394 关注
  • Logseq

    Logseq 是一个隐私优先、开源的知识库工具。

    Logseq is a joyful, open-source outliner that works on top of local plain-text Markdown and Org-mode files. Use it to write, organize and share your thoughts, keep your to-do list, and build your own digital garden.

    7 引用 • 69 回帖 • 1 关注
  • 持续集成

    持续集成(Continuous Integration)是一种软件开发实践,即团队开发成员经常集成他们的工作,通过每个成员每天至少集成一次,也就意味着每天可能会发生多次集成。每次集成都通过自动化的构建(包括编译,发布,自动化测试)来验证,从而尽早地发现集成错误。

    15 引用 • 7 回帖 • 1 关注
  • 游戏

    沉迷游戏伤身,强撸灰飞烟灭。

    180 引用 • 821 回帖