大数跨境
0
0

我用 Java 把二维码玩出花了

我用 Java 把二维码玩出花了 终码一生
2025-11-14
2
点击“终码一生”,关注,置顶公众号
每日技术干货,第一时间送达!

现在任何东西都能整出个二维码?

  • 微信支付?扫码。
  • 加好友?扫码。
  • 点菜?扫码。
  • 领优惠券?扫码。
  • 连 Wi-Fi?扫码。
  • 打开厕所门?也扫码……(别问我怎么知道的)
二维码已经彻底渗透到我们生活的每个角落。作为一名干了八年 Java 的程序员(主要在摸鱼,但也干活),我最近接到一个需求:
“我们要给用户生成动态的登录二维码,另外还要支持活动海报、带 logo 的分享码、临时访客二维码、带参数的推广码……你搞一下,应该不难吧?”
我嘴上说着“简单”,心里却在想:
你知道二维码有多少种花样吗?!
01
业务分析:二维码到底有几种玩法?
我们先冷静分析一下业务需求,把“二维码”拆解成几个典型的应用场景:
场景名称
特点描述
登录二维码
临时有效,常变化,内容是一个 token 或 URL
活动海报二维码
嵌入图片中,需高颜值,对清晰度有要求
带 logo 的二维码
中间加 logo 图标,用户更容易识别品牌
参数推广二维码
携带用户 ID、推广码等参数,可用于追踪来源
临时访客二维码
时间敏感,可能加密,甚至设定失效时间
简而言之,二维码不仅是一个图,还要“有脑子” 。
02
技术选型:选对工具,事半功倍
在 Java 世界,要生成二维码,主流有两个选择:
  • ZXing (Zebra Crossing):Google 出品,经典老牌,稳定可靠。
  • QrCode (来自 com.google.zxing.qrcode):轻量级,适合快速开发。
  • QRCodeUtils (封装工具类):自己撸一点封装,方便复用。
我选的是 ZXing + 自定义封装。
理由如下:
  • 社区活跃,有问题能搜到;
  • 支持二维码 + 条形码;
  • 可配置参数多,能满足各种奇葩需求;
  • 最重要的:依赖不重 ,摸鱼时也能快速搞定!
03
实战演示:Java 手把手教你生成各种二维码
1. 引入 Maven 依赖
<dependency>
  <groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
<version>3.5.2</version>
</dependency>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>javase</artifactId>
<version>3.5.2</version>
</dependency>
2. 封装一个二维码工具类QrCodeUtils.java
/**
 * 天天摸鱼的 Java 工程师出品
 * 通用二维码生成工具类
 */
publicclass QrCodeUtils {

    /**
     * 生成普通二维码并保存为图片文件
     *
     * @param content  二维码内容
     * @param filePath 保存路径(绝对路径)
     * @param width    宽度
     * @param height   高度
     * @throws Exception
     */
    public static void generateSimpleQrCode(String content, String filePath, int width, int height) throws Exception {
        // 编码参数设置
        Map<EncodeHintType, Object> hints = new HashMap<>();
        hints.put(EncodeHintType.CHARACTER_SET, "UTF-8"); // 编码类型
        hints.put(EncodeHintType.MARGIN, 1);              // 边距

        BitMatrix bitMatrix = new MultiFormatWriter().encode(
                content,
                BarcodeFormat.QR_CODE,
                width,
                height,
                hints
        );

        Path path = new File(filePath).toPath();
        MatrixToImageWriter.writeToPath(bitMatrix, "PNG", path);
    }

    /**
     * 生成带 Logo 的二维码
     *
     * @param content   二维码内容
     * @param logoPath  logo 图片路径
     * @param outputPath 输出二维码路径
     */
    public static void generateQrCodeWithLogo(String content, String logoPath, String outputPath) throws Exception {
        int width = 300;
        int height = 300;

        Map<EncodeHintType, Object> hints = new HashMap<>();
        hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
        hints.put(EncodeHintType.MARGIN, 1);
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H); // 容错率高,避免 logo 遮挡

        BitMatrix bitMatrix = new MultiFormatWriter().encode(
                content, BarcodeFormat.QR_CODE, width, height, hints
        );

        // 生成二维码图像
        BufferedImage qrImage = MatrixToImageWriter.toBufferedImage(bitMatrix, new MatrixToImageConfig());

        // 加载 logo 图片
        BufferedImage logo = ImageIO.read(new File(logoPath));

        int logoWidth = qrImage.getWidth() / 5;
        int logoHeight = qrImage.getHeight() / 5;

        // 计算 logo 放置位置(居中)
        int x = (qrImage.getWidth() - logoWidth) / 2;
        int y = (qrImage.getHeight() - logoHeight) / 2;

        // 合并图片
        Graphics2D g = qrImage.createGraphics();
        g.drawImage(logo, x, y, logoWidth, logoHeight, null);
        g.dispose();

        ImageIO.write(qrImage, "PNG", new File(outputPath));
    }
}
3. 实战调用:生成一个带参数的推广码
public class Main {
    public static void main(String[] args) throws Exception {
        String content = "https://yourdomain.com/register?ref=userid_123456";
        String savePath = "D:/qrcode/promo.png";

        QrCodeUtils.generateSimpleQrCode(content, savePath, 300, 300);
        System.out.println("推广二维码生成成功,快去扫码看看!");
    }
}
4. 再来一个更骚的:带 Logo 的品牌码
public class LogoDemo {
    public static void main(String[] args) throws Exception {
        String content = "https://yourapp.com/share?id=abc123";
        String logo = "D:/logo/logo.png";
        String output = "D:/qrcode/share_with_logo.png";

        QrCodeUtils.generateQrCodeWithLogo(content, logo, output);
        System.out.println("带 Logo 的二维码已生成!");
    }
}
04
最佳实践 & 踩坑总结(摸鱼人血泪经验)
✅ 推荐做法:
  • 高容错 + logo :记得设置 ErrorCorrectionLevel.H,否则 logo 会导致识别失败。
  • 二维码尺寸 :建议大于 250x250,避免在海报中模糊。
  • 内容长度 :控制长度,避免生成失败(尤其是带参数 URL)。
❌ 踩过的坑:
  • 设置边距为 0 会导致大部分扫码器识别失败(别问怎么知道的)。
  • Logo 太大?二维码直接“失忆”。
  • 文件路径拼错?OutputStream 直接挂。
05
后记:二维码虽小,五脏俱全
别看二维码只有黑白小格子,其背后能承载的业务逻辑、营销策略、用户行为追踪,可比你写的 if else 高级多了。
记住一句老话:“二维码是连接线下与线上最朴素、最强大的桥梁。 ”
来源:juejin.cn/post/7527881245239001126
END
PS:防止找不到本篇文章,可以收藏点赞,方便翻阅查找哦。



往期推荐



SpringBoot中这10个神仙功能,惊艳到我了!

阿里又开源了一个顶级 Java 项目!

她说Gin比SpringBoot更快,我用2行代码,让她闭嘴!

面试官:try catch 应该在 for 循环里面还是外面?

拒绝写重复代码,试试这套开源的SpringBoot组件,效率翻倍~

成年人欲望程度排行榜TOP 10


【声明】内容源于网络
0
0
终码一生
开发者聚集地。分享Java相关开发技术(JVM,多线程,高并发,性能调优等),开源项目,常见开发问题和前沿科技资讯!
内容 1876
粉丝 0
终码一生 开发者聚集地。分享Java相关开发技术(JVM,多线程,高并发,性能调优等),开源项目,常见开发问题和前沿科技资讯!
总阅读1.4k
粉丝0
内容1.9k