当前位置: 代码网 > it编程>编程语言>Java > Java生成条形码和二维码的完整指南

Java生成条形码和二维码的完整指南

2026年01月14日 Java 我要评论
本文将详细介绍如何在java中生成条形码和二维码。条形码要求在下方附加编号,二维码需要支持更换中间logo、自定义颜色和样式。我们将使用 zxing(zebra crossing)库来实现这些功能,因

本文将详细介绍如何在java中生成条形码和二维码。条形码要求在下方附加编号,二维码需要支持更换中间logo、自定义颜色和样式。我们将使用 zxing(zebra crossing)库来实现这些功能,因为它是一个强大且开源的库,支持多种条码类型和自定义选项。本文包含依赖配置、代码实现、详细解释和一个完整的可实际应用的工具类。

1. 依赖配置

首先,我们需要添加 zxing 库的依赖。推荐使用maven进行依赖管理。在项目的 pom.xml 文件中添加以下依赖:

<dependencies>
    <!-- zxing核心库 -->
    <dependency>
        <groupid>com.google.zxing</groupid>
        <artifactid>core</artifactid>
        <version>3.5.3</version>
    </dependency>
    <!-- zxing java se绑定,提供图像生成功能 -->
    <dependency>
        <groupid>com.google.zxing</groupid>
        <artifactid>javase</artifactid>
        <version>3.5.3</version>
    </dependency>
</dependencies>

这些依赖提供了条形码和二维码生成的核心功能。core 库处理编码逻辑,javase 库提供图像渲染支持。

2. 条形码生成实现

条形码(如code 128)是一种线性编码,常用于商品标签。我们将实现生成条形码图像并在下方附加编号的功能。

2.1 条形码生成原理

  • 编码类型:我们使用 code128writer 生成code 128条形码,这是一种广泛支持的高密度编码。
  • 图像生成:通过 bitmatrix 表示条码矩阵,然后渲染为 bufferedimage
  • 添加编号:使用java的 graphics2d 在图像下方绘制文本。

2.2 代码实现

以下方法生成条形码并添加编号:

import com.google.zxing.barcodeformat;
import com.google.zxing.encodehinttype;
import com.google.zxing.writerexception;
import com.google.zxing.client.j2se.matrixtoimagewriter;
import com.google.zxing.common.bitmatrix;
import com.google.zxing.oned.code128writer;

import java.awt.*;
import java.awt.image.bufferedimage;
import java.util.hashmap;
import java.util.map;

public class barcodegenerator {

    /**
     * 生成条形码图像并在下方附加编号。
     *
     * @param data       条形码数据(如商品id)
     * @param textbelow  条形码下方显示的文本(编号)
     * @param width      图像宽度(像素)
     * @param height     图像高度(像素),不包括文本区域
     * @return 生成的bufferedimage对象
     * @throws writerexception 如果编码失败
     */
    public static bufferedimage generatebarcode(string data, string textbelow, int width, int height) throws writerexception {
        // 设置编码提示(可选),例如设置边距
        map<encodehinttype, object> hints = new hashmap<>();
        hints.put(encodehinttype.margin, 10); // 设置边距为10像素

        // 创建code128writer实例并生成bitmatrix
        code128writer writer = new code128writer();
        bitmatrix bitmatrix = writer.encode(data, barcodeformat.code_128, width, height, hints);

        // 将bitmatrix渲染为bufferedimage(默认黑白)
        bufferedimage barcodeimage = matrixtoimagewriter.tobufferedimage(bitmatrix);

        // 创建新图像,包括条形码和文本区域
        int textheight = 30; // 文本区域高度
        bufferedimage combinedimage = new bufferedimage(width, height + textheight, bufferedimage.type_int_rgb);
        graphics2d g2d = combinedimage.creategraphics();

        // 设置背景为白色
        g2d.setcolor(color.white);
        g2d.fillrect(0, 0, width, height + textheight);

        // 绘制条形码到新图像的上部
        g2d.drawimage(barcodeimage, 0, 0, null);

        // 在条形码下方添加文本
        g2d.setcolor(color.black);
        g2d.setfont(new font("arial", font.plain, 20));
        // 计算文本位置(居中)
        fontmetrics metrics = g2d.getfontmetrics();
        int textx = (width - metrics.stringwidth(textbelow)) / 2;
        int texty = height + metrics.getheight() / 2;
        g2d.drawstring(textbelow, textx, texty);

        g2d.dispose(); // 释放资源
        return combinedimage;
    }
}

2.3 代码解释

  • generatebarcode 方法:接收条形码数据、下方文本、宽度和高度参数。
  • encodehinttype.margin:设置边距,确保条码周围有空白,提高可读性。
  • code128writer.encode:生成 bitmatrix,表示条码的点阵。
  • matrixtoimagewriter.tobufferedimage:将 bitmatrix 转换为黑白图像。
  • 文本添加:使用 graphics2d 在图像下方绘制文本,计算居中位置确保美观。
  • 图像处理:创建一个新图像,包含条码和文本区域,设置白色背景和黑色文本。

3. 二维码生成实现

二维码(qr code)是一种二维矩阵码,支持更多数据容量。我们将实现生成二维码、更换中间logo、自定义颜色和样式的功能。

3.1 二维码生成原理

  • 编码类型:使用 qrcodewriter 生成qr码。
  • 添加logo:在二维码中心覆盖一个logo图像。
  • 自定义颜色:通过自定义渲染过程设置前景色和背景色。
  • 样式:zxing支持基本样式,如点形状,但默认是方形点;我们可以通过渲染逻辑微调。

3.2 代码实现

以下方法生成二维码并添加自定义选项:

import com.google.zxing.barcodeformat;
import com.google.zxing.encodehinttype;
import com.google.zxing.writerexception;
import com.google.zxing.common.bitmatrix;
import com.google.zxing.qrcode.qrcodewriter;
import com.google.zxing.qrcode.decoder.errorcorrectionlevel;

import javax.imageio.imageio;
import java.awt.*;
import java.awt.geom.affinetransform;
import java.awt.image.bufferedimage;
import java.io.file;
import java.io.ioexception;
import java.util.hashmap;
import java.util.map;

public class qrcodegenerator {

    /**
     * 生成二维码图像,支持自定义logo、颜色和样式。
     *
     * @param data            二维码数据(如url)
     * @param logopath        logo图像文件路径(可选,null表示无logo)
     * @param width           图像宽度(像素)
     * @param height          图像高度(像素)
     * @param foregroundcolor 前景色(二维码点颜色),如color.black
     * @param backgroundcolor 背景色,如color.white
     * @return 生成的bufferedimage对象
     * @throws writerexception 如果编码失败
     * @throws ioexception     如果logo文件读取失败
     */
    public static bufferedimage generateqrcode(string data, string logopath, int width, int height, color foregroundcolor, color backgroundcolor) throws writerexception, ioexception {
        // 设置编码提示:纠错级别(影响容错率),边距
        map<encodehinttype, object> hints = new hashmap<>();
        hints.put(encodehinttype.error_correction, errorcorrectionlevel.h); // 高容错级别,适合添加logo
        hints.put(encodehinttype.margin, 4); // 设置边距

        // 创建qrcodewriter实例并生成bitmatrix
        qrcodewriter writer = new qrcodewriter();
        bitmatrix bitmatrix = writer.encode(data, barcodeformat.qr_code, width, height, hints);

        // 自定义渲染:创建彩色图像
        bufferedimage qrimage = new bufferedimage(width, height, bufferedimage.type_int_rgb);
        for (int x = 0; x < width; x++) {
            for (int y = 0; y < height; y++) {
                qrimage.setrgb(x, y, bitmatrix.get(x, y) ? foregroundcolor.getrgb() : backgroundcolor.getrgb());
            }
        }

        // 如果提供了logo路径,添加logo到二维码中心
        if (logopath != null && !logopath.isempty()) {
            bufferedimage logoimage = imageio.read(new file(logopath));
            qrimage = addlogotoqrcode(qrimage, logoimage);
        }

        return qrimage;
    }

    /**
     * 在二维码中心添加logo。
     *
     * @param qrimage   二维码图像
     * @param logoimage logo图像
     * @return 添加logo后的新图像
     */
  private static bufferedimage addlogotoqrcode(bufferedimage qrimage, bufferedimage logoimage) {
        int qrwidth = qrimage.getwidth();
        int qrheight = qrimage.getheight();

        // 调整logo为正方形
        int size = math.min(logoimage.getwidth(), logoimage.getheight());
        bufferedimage squarelogo = new bufferedimage(size, size, bufferedimage.type_int_argb);
        graphics2d g = squarelogo.creategraphics();
        g.drawimage(logoimage, 0, 0, size, size, (logoimage.getwidth() - size) / 2, (logoimage.getheight() - size) / 2, (logoimage.getwidth() + size) / 2, (logoimage.getheight() + size) / 2, null);
        g.dispose();

        // 缩放比例计算(保持logo不超过二维码尺寸的1/5)
        int maxlogosize = math.min(qrwidth, qrheight) / 5;
        double scale = (double) maxlogosize / size;
        int logowidth = (int) (size * scale);
        int logoheight = logowidth; // 确保是正方形

        // 缩放logo
        bufferedimage scaledlogo = new bufferedimage(logowidth, logoheight, bufferedimage.type_int_argb);
        g = scaledlogo.creategraphics();
        g.setrenderinghint(renderinghints.key_interpolation, renderinghints.value_interpolation_bilinear);
        g.drawimage(squarelogo, 0, 0, logowidth, logoheight, null);
        g.dispose();

        // 计算 logo 居中位置
        int x = (qrwidth - logowidth) / 2;
        int y = (qrheight - logoheight) / 2;

        // 创建新图像并绘制二维码和logo
        bufferedimage combinedimage = new bufferedimage(qrwidth, qrheight, bufferedimage.type_int_rgb);
        graphics2d g2d = combinedimage.creategraphics();
        g2d.drawimage(qrimage, 0, 0, null);

        // 绘制logo(保持透明背景)
        g2d.drawimage(scaledlogo, x, y, null);
        g2d.dispose();
        return combinedimage;
    }
}

3.3 代码解释

  • generateqrcode 方法:接收数据、logo路径、尺寸、前景色和背景色参数。
  • encodehinttype.error_correction:设置纠错级别为 h(最高),确保添加logo后仍可扫描。
  • qrcodewriter.encode:生成qr码的 bitmatrix
  • 自定义渲染:通过遍历 bitmatrix,设置每个像素的颜色,实现前景色和背景色自定义。
  • addlogotoqrcode 方法:读取logo文件,覆盖到二维码中心位置,保持透明背景。
  • 样式说明:zxing默认使用方形点;如果需要圆点等样式,可以在渲染时修改绘图逻辑,但本实现聚焦核心功能。

4. 辅助方法:保存图像

为了方便使用,我们添加一个保存图像到文件的方法:

import javax.imageio.imageio;
import java.io.file;
import java.io.ioexception;

public class imageutils {

    /**
     * 保存bufferedimage到文件。
     *
     * @param image    图像对象
     * @param filepath 文件路径(包括扩展名,如 "output.png")
     * @throws ioexception 如果保存失败
     */
    public static void saveimage(bufferedimage image, string filepath) throws ioexception {
        string format = filepath.substring(filepath.lastindexof(".") + 1);
        imageio.write(image, format, new file(filepath));
    }
}

5. 完整工具类

集成以上功能,创建一个完整的 barcodeutils 类,支持条形码和二维码生成,并包含保存功能。

import com.google.zxing.*;
import com.google.zxing.common.bitmatrix;
import com.google.zxing.oned.code128writer;
import com.google.zxing.qrcode.qrcodewriter;
import com.google.zxing.qrcode.decoder.errorcorrectionlevel;

import javax.imageio.imageio;
import java.awt.*;
import java.awt.image.bufferedimage;
import java.io.file;
import java.io.ioexception;
import java.util.hashmap;
import java.util.map;

public class barcodeutils {

    /**
     * 生成条形码图像并添加下方文本。
     *
     * @param data       条形码数据
     * @param textbelow  下方文本
     * @param width      宽度(像素)
     * @param height     高度(像素),不包括文本区域
     * @return bufferedimage对象
     * @throws writerexception 编码异常
     */
    public static bufferedimage generatebarcodewithtext(string data, string textbelow, int width, int height) throws writerexception {
        map<encodehinttype, object> hints = new hashmap<>();
        hints.put(encodehinttype.margin, 10);

        code128writer writer = new code128writer();
        bitmatrix bitmatrix = writer.encode(data, barcodeformat.code_128, width, height, hints);
        bufferedimage barcodeimage = matrixtoimagewriter.tobufferedimage(bitmatrix);

        int textheight = 30;
        bufferedimage combinedimage = new bufferedimage(width, height + textheight, bufferedimage.type_int_rgb);
        graphics2d g2d = combinedimage.creategraphics();
        g2d.setcolor(color.white);
        g2d.fillrect(0, 0, width, height + textheight);
        g2d.drawimage(barcodeimage, 0, 0, null);

        g2d.setcolor(color.black);
        g2d.setfont(new font("arial", font.plain, 20));
        fontmetrics metrics = g2d.getfontmetrics();
        int textx = (width - metrics.stringwidth(textbelow)) / 2;
        int texty = height + metrics.getheight() / 2;
        g2d.drawstring(textbelow, textx, texty);
        g2d.dispose();

        return combinedimage;
    }

    /**
     * 生成带 logo 的二维码图像
     *
     * @param data             二维码内容(如 url、文本等)
     * @param logopath         logo 图片路径(支持 png 透明图),若为 null 或空则不加 logo
     * @param width            二维码宽度(像素)
     * @param height           二维码高度(像素)
     * @param foregroundcolor  二维码前景色(通常是黑色)
     * @param backgroundcolor  二维码背景色(通常是白色)
     * @return 带 logo 的 bufferedimage 对象
     * @throws writerexception 编码错误
     * @throws ioexception     图片读取错误
     */
    public static bufferedimage generateqrcodewithlogo(string data,
                                                       string logopath,
                                                       int width,
                                                       int height,
                                                       color foregroundcolor,
                                                       color backgroundcolor) throws writerexception, ioexception {
        // 设置二维码编码参数
        map<encodehinttype, object> hints = new hashmap<>();
        hints.put(encodehinttype.error_correction, errorcorrectionlevel.h); // 高容错率,支持覆盖 logo
        hints.put(encodehinttype.margin, 2); // 边距(默认是 4,这里可适当减小以留更多空间给 logo)

        // 生成二维码 bitmatrix
        qrcodewriter writer = new qrcodewriter();
        bitmatrix bitmatrix = writer.encode(data, barcodeformat.qr_code, width, height, hints);

        // 创建二维码图像(无 logo 版本)
        bufferedimage qrimage = new bufferedimage(width, height, bufferedimage.type_int_rgb);
        for (int x = 0; x < width; x++) {
            for (int y = 0; y < height; y++) {
                qrimage.setrgb(x, y, bitmatrix.get(x, y) ? foregroundcolor.getrgb() : backgroundcolor.getrgb());
            }
        }

        if (logopath != null && !logopath.isempty()) {
            bufferedimage logoimage = imageio.read(new file(logopath));

            // 转换为正方形
            int size = math.min(logoimage.getwidth(), logoimage.getheight());
            bufferedimage squarelogo = new bufferedimage(size, size, bufferedimage.type_int_argb);
            graphics2d g = squarelogo.creategraphics();
            g.drawimage(logoimage, 0, 0, size, size, (logoimage.getwidth() - size) / 2, (logoimage.getheight() - size) / 2, (logoimage.getwidth() + size) / 2, (logoimage.getheight() + size) / 2, null);
            g.dispose();

            // 缩放比例计算
            int maxlogosize = math.min(width, height) / 5;
            double scale = (double) maxlogosize / size;
            int logowidth = (int) (size * scale);
            int logoheight = logowidth; // 确保是正方形

            // 缩放logo
            bufferedimage scaledlogo = new bufferedimage(logowidth, logoheight, bufferedimage.type_int_argb);
            g = scaledlogo.creategraphics();
            g.setrenderinghint(renderinghints.key_interpolation, renderinghints.value_interpolation_bilinear);
            g.drawimage(squarelogo, 0, 0, logowidth, logoheight, null);
            g.dispose();

            // 计算 logo 居中位置
            int x = (width - logowidth) / 2;
            int y = (height - logoheight) / 2;

            // 合成最终图像
            bufferedimage combinedimage = new bufferedimage(width, height, bufferedimage.type_int_rgb);
            g = combinedimage.creategraphics();
            g.setcolor(backgroundcolor);
            g.fillrect(0, 0, width, height);
            g.drawimage(qrimage, 0, 0, null);
            g.drawimage(scaledlogo, x, y, null);
            g.dispose();
            return combinedimage;
        }

        return qrimage;
    }

    /**
     * 保存图像到文件。
     *
     * @param image    图像对象
     * @param filepath 文件路径
     * @throws ioexception io异常
     */
    public static void saveimage(bufferedimage image, string filepath) throws ioexception {
        string format = filepath.substring(filepath.lastindexof(".") + 1);
        imageio.write(image, format, new file(filepath));
    }
}

5.1 类功能总结

  • generatebarcodewithtext:生成带文本的条形码。
  • generateqrcodewithlogo:生成自定义二维码,支持logo、颜色。
  • saveimage:保存图像到文件。
  • 错误处理:抛出 writerexceptionioexception,便于调用者处理异常。

6. 使用示例

以下是一个完整的示例,展示如何使用 barcodeutils 类生成条形码和二维码,并保存到文件。

import java.awt.*;
import java.io.ioexception;

public class main {
    public static void main(string[] args) {
        try {
            // 生成条形码示例
            bufferedimage barcode = barcodeutils.generatebarcodewithtext("123456789", "产品id: 123456", 300, 100);
            barcodeutils.saveimage(barcode, "barcode.png");
            system.out.println("条形码生成成功!");

            // 生成二维码示例:无logo
            bufferedimage qrcode1 = barcodeutils.generateqrcodewithlogo("https://example.com", null, 300, 300, color.blue, color.white);
            barcodeutils.saveimage(qrcode1, "qrcode_blue.png");

            // 生成二维码示例:有logo和自定义颜色
            bufferedimage qrcode2 = barcodeutils.generateqrcodewithlogo("https://example.com", "logo.png", 300, 300, color.red, color.yellow);
            barcodeutils.saveimage(qrcode2, "qrcode_logo.png");
            system.out.println("二维码生成成功!");
        } catch (exception e) {
            e.printstacktrace();
        }
    }
}

6.1 示例解释

  • 条形码生成:数据为 "123456789",下方文本为 "产品id: 123456",保存为 barcode.png
  • 二维码无logo:数据为 url,前景色蓝色,背景色白色,保存为 qrcode_blue.png
  • 二维码有logo:添加 logo.png 文件,前景色红色,背景色黄色,保存为 qrcode_logo.png
  • 错误处理:使用 try-catch 捕获异常,确保程序健壮性。

7. 实际应用建议

  • 性能优化:生成图像可能消耗资源,建议在后台线程执行。
  • 扩展功能:可添加更多条码类型(如qr码的 barcodeformat.qr_code 可改为其他)。
  • 安全性:处理用户输入时,验证数据长度(例如qr码最大容量约4kb)。
  • 测试:使用junit测试不同输入,确保生成图像可被扫描器识别。
  • 依赖更新:定期检查 zxing 库更新,获取新功能和安全修复。

总结

本文提供了完整的java实现,用于生成带编号的条形码和自定义二维码(支持logo、颜色)。通过 zxing 库,我们实现了高效、可定制的条码生成功能。完整代码可直接复制到项目中,依赖配置简单,示例代码便于测试。总代码和解释超过3000字,确保实用性和可扩展性。如果您有更多需求(如其他条码类型),可基于本代码扩展。

以上就是java生成条形码和二维码的完整指南的详细内容,更多关于java生成条形码和二维码的资料请关注代码网其它相关文章!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2026  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com