营销级二维码生成术:Java如何打造专属标识

关注我的公众号:【编程朝花夕拾】,可获取首发内容。

01 引言

二维码技术已经非常成熟了,应用非常广泛,如收付款、交友、旅游等。作为技术人,如此好用的二维码是如何生成的呢?

二维码的生成有很多小工具已经实现的非常好了,如草料二维码、掘金插件的快捷工具等。要集成在项目中的话,这些小工具用起来就没有那么方便了,我们就需要定制属于自家的二维码。

02 二维码

要生成二维码我们需要依赖一些优秀的开源框架,本章将介绍两种:

2.1 ZXing

ZXing是谷歌开源的一款功能强大、多格式的条形码(1D)和二维码(2D)的图像处理库。它的主要强项在于 解码(读取/识别),但也包含基本的编码(生成)功能。

Github地址:github.com/zxing/zxing

2.2 QR-Code-generator

QR-Code-generator是一款通用的库, 专注于生成 QR Code 二维码的开源库。它的目标是提供简单、轻量级、高效且可移植的 QR 码生成解决方案。代码库非常小巧(核心 C 实现只有两个源文件),编译后体积小,运行时内存占用低,生成速度快。

Github地址:github.com/nayuki/QR-C...

03 ZXing实战

需要的依赖

xml 复制代码
<dependency>
    <groupId>com.google.zxing</groupId>
    <artifactId>core</artifactId>
    <version>3.3.3</version>
</dependency>
<dependency>
    <groupId>com.google.zxing</groupId>
    <artifactId>javase</artifactId>
    <version>3.3.3</version>
</dependency>

3.1 普通的二维码

java 复制代码
@Test
void test01() throws Exception {
    String content = "编程朝花夕拾";
    int width = 300, height = 300;

    // 创建矩阵
    BitMatrix matrix = new MultiFormatWriter().encode(
            content,
            BarcodeFormat.QR_CODE,
            width,
            height,
            // 设置边框和编码
            Map.of(EncodeHintType.MARGIN, 1, EncodeHintType.CHARACTER_SET, "utf-8") 
    );

    MatrixToImageWriter.writeToPath(matrix, "PNG", Paths.get("qrcode.png"));
}

结果

3.2 带logo的二维码

java 复制代码
@Test
void test02() throws Exception {
    // 读取二维码
    BufferedImage qrImage = ImageIO.read(new File("qrcode.png"));
    Graphics2D graphics = qrImage.createGraphics();

    // 读取Logo并缩放
    BufferedImage logo = ImageIO.read(new File("src/main/resources/bgimages/logo.png"));
    int logoSize = qrImage.getWidth() / 5; // Logo大小为二维码1/5
    int x = (qrImage.getWidth() - logoSize) / 2;
    int y = (qrImage.getHeight() - logoSize) / 2;

    // 绘制Logo
    graphics.drawImage(logo, x, y, logoSize, logoSize, null);
    graphics.dispose();

    // 保存带Logo的二维码
    ImageIO.write(qrImage, "PNG", new File("qrcode_logo.png"));
}

结果

3.3 带文案的二维码

java 复制代码
@Test
void test03() throws Exception {
    String text = "测试文案";
    // 读取二维码
    BufferedImage qrImage = ImageIO.read(new File("qrcode.png"));
    int textHeight = 30; // 文字区域高度

    // 创建新画布(二维码高度 + 文字区域)
    BufferedImage combined = new BufferedImage(
            qrImage.getWidth(),
            qrImage.getHeight() + textHeight,
            BufferedImage.TYPE_INT_RGB
    );

    Graphics2D g = combined.createGraphics();
    g.setBackground(Color.WHITE);
    g.clearRect(0, 0, combined.getWidth(), combined.getHeight());

    // 绘制二维码
    g.drawImage(qrImage, 0, 0, null);

    // 绘制文字(居中)
    g.setColor(Color.BLACK);
    g.setFont(new Font("微软雅黑", Font.PLAIN, 20));
    int textWidth = g.getFontMetrics().stringWidth(text);
    int textX = (combined.getWidth() - textWidth) / 2;
    int textY = qrImage.getHeight() + 25;
    g.drawString(text, textX, textY);
    g.dispose();

    ImageIO.write(combined, "PNG", new File("qrcode_text.png"));
}

结果

3.4 解析二维码

java 复制代码
@Test
void test04() throws Exception {
    BufferedImage image = ImageIO.read(new File("qrcode.png"));
    LuminanceSource source = new BufferedImageLuminanceSource(image);
    Result result = new MultiFormatReader().decode(new BinaryBitmap(new HybridBinarizer(source)));
    System.out.println("解码内容: " + result.getText());
    // 解码内容: 编程朝花夕拾
}

3.5 使用技巧

ZXing提供了丰富的功能,熟练使用需要了解其API,门槛稍高。尤其需要对Graphics2D了解,才能绘制准确的二维码。Hutool这款国产的工具包,为了我们封装了更加方便的API,无需关心内部实现,之间输入关键参数即可。

需要引入Hutool的依赖:

xml 复制代码
<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>${latest.version}</version>
</dependency>

案例:

java 复制代码
@Test
void test03() throws IOException {
    QrConfig qrConfig = new QrConfig();
    qrConfig.setImg(new File("src/main/resources/bgimages/watermark.png"));
    BufferedImage generate = QrCodeUtil.generate("编程朝花夕拾!", qrConfig);
    ImageIO.write(generate, "png", new File("qr-code3.png"));
}

结果

生成一个带logo的二维码,比ZXing简单多了。Hutool对二维码的封装是基于ZXing的,所以使用时也需要引入ZXing的依赖。

04 QR-Code-generator实战

QR-Code-generator没有Maven依赖,但是有jar,我们可以通过将jar导入项目或者上传到自己的私服使用。

java 复制代码
@Test
void test01() throws IOException {
    QrCode qrCode = QrCode.encodeText("编程朝花夕拾", Ecc.LOW);
    System.out.println(qrCode.size);
    BufferedImage image = toImage(qrCode, 2, 2);
    ImageIO.write(image, "png", new File("qr-code.png"));
}

其中toImage也是官方提供的:

摘录方法:

java 复制代码
private BufferedImage toImage(QrCode qr, int scale, int border) {
    return toImage(qr, scale, border, 0xFFFFFF, 0x000000);
}

private BufferedImage toImage(QrCode qr, int scale, int border, int lightColor, int darkColor) {
    Objects.requireNonNull(qr);
    if (scale <= 0 || border < 0)
        throw new IllegalArgumentException("Value out of range");
    if (border > Integer.MAX_VALUE / 2 || qr.size + border * 2L > Integer.MAX_VALUE / scale)
        throw new IllegalArgumentException("Scale or border too large");

    BufferedImage result = new BufferedImage((qr.size + border * 2) * scale, (qr.size + border * 2) * scale, BufferedImage.TYPE_INT_RGB);
    for (int y = 0; y < result.getHeight(); y++) {
        for (int x = 0; x < result.getWidth(); x++) {
            boolean color = qr.getModule(x / scale - border, y / scale - border);
            result.setRGB(x, y, color ? darkColor : lightColor);
        }
    }
    return result;
}

如果需要添加logo或者文案时,需要和上面的ZXing的案例,自行添加即可。

结果

05 小结

特性 ZXing QR-Code-generator
核心功能 强大的多格式条码解码 + 基础编码 专注高效的 QR Code 生成
支持的条码类型 极其广泛 (QR, Data Matrix, PDF417, 各种1D码等) 仅 QR Code 和 Micro QR Code
解码能力 非常强大 (是其核心优势) (纯生成库)
生成能力 支持多种格式生成,但定制性通常不如专用库 优秀 (专注于 QR 生成,轻量高效)
跨平台/语言支持 广泛 (Java 核心 + 多语言/平台端口) 极佳 (C 核心 + 众多轻量级语言包装器)
库大小/依赖 相对较大 (尤其 Java 核心),可能有较多依赖 非常轻量 (核心 C 仅两文件,无依赖)
资源消耗 相对较高 非常低 (适合嵌入式/资源受限环境)
主要优势 全能解码,多格式支持,移动端集成成熟 轻量,高效,易移植,专注 QR 生成
典型应用场景 扫码 App、需要识别多种条码的系统 Web/App/嵌入式中生成 QR 码、需要轻量集成的场景

看了这两款的开源二维码技术,你更喜欢那一种呢?

相关推荐
自由鬼1 小时前
如何处理Y2K38问题
java·运维·服务器·程序人生·安全·操作系统
_oP_i4 小时前
RabbitMQ 队列配置设置 RabbitMQ 消息监听器的并发消费者数量java
java·rabbitmq·java-rabbitmq
Monkey-旭4 小时前
Android Bitmap 完全指南:从基础到高级优化
android·java·人工智能·计算机视觉·kotlin·位图·bitmap
我爱996!4 小时前
SpringMVC——响应
java·服务器·前端
小宋10215 小时前
多线程向设备发送数据
java·spring·多线程
大佐不会说日语~6 小时前
Redis高频问题全解析
java·数据库·redis
寒水馨6 小时前
Java 17 新特性解析与代码示例
java·开发语言·jdk17·新特性·java17
启山智软6 小时前
选用Java开发商城的优势
java·开发语言
鹦鹉0076 小时前
SpringMVC的基本使用
java·spring·html·jsp
R cddddd6 小时前
Maven模块化开发与设计笔记
java·maven