二维码与条形码
直接将二维码和一维条形码生成为 PDF 文档、生成为独立的 PNG/SVG 图像,或将它们放置到现有 PDF 的页面上。条形码生成位于一个特性标志之后,以保持核心库的轻量。
绑定覆盖情况。 条形码相关的接口分为两个不同的部分:
- 一次性 PDF 构造器(
Pdf::from_qrcode/Pdf::from_barcode)以及底层的BarcodeGenerator—— 仅在 Rust 中公开。- 条形码图像句柄家族(
generate_qr_code、generate_barcode、add_barcode_to_page),由 C ABI 的pdf_generate_qr_code/pdf_generate_barcode/pdf_add_barcode_to_page函数支撑 —— 在 Swift、Go 和 C# 中公开,也可通过 FFI 从 C/C++ 直接调用。- SVG 生成器(
generate_qr_svg/generate_barcode_svg)—— 在 Python 和 Rust 中公开。下面每个方法都标注了实际公开它的语言。不要假设某个方法在未列出的绑定中存在。
需要的特性标志: barcodes
# Cargo.toml
[dependencies]
pdf_oxide = { version = "0.3", features = ["barcodes"] }
如何将二维码生成为 PDF?
在 Rust 中最快捷的方式是使用一次性的 Pdf::from_qrcode 构造器。pdf_oxide 会将二维码写入一个单页 PDF,你可以直接保存它。
Rust:
use pdf_oxide::api::Pdf;
fn main() -> Result<(), Box<dyn std::error::Error>> {
// QR code (300px) -> single-page PDF
let pdf = Pdf::from_qrcode("https://example.com")?;
pdf.save("qrcode.pdf")?;
// 1D barcode -> single-page PDF
use pdf_oxide::writer::barcode::BarcodeType;
let pdf = Pdf::from_barcode(BarcodeType::Code128, "ABC-12345")?;
pdf.save("barcode.pdf")?;
Ok(())
}
如何生成条形码图像(PNG/SVG)而非 PDF?
当你希望将编码后的图形作为图像获取时——用于嵌入现有文档、发送到 Web 前端,或打印到标签上——请使用图像句柄家族或 SVG 生成器。规范的方法名是 generate_qr_code 和 generate_barcode(旧的 generate_qr / generate_code 名称不属于公开接口)。
Swift(BarcodeImage.generateQrCode、BarcodeImage.generateBarcode):
import PdfOxide
// QR code. errorCorrection: 0=L 1=M 2=Q 3=H. sizePx: module-grid pixel size.
let qr = try BarcodeImage.generateQrCode("https://example.com",
errorCorrection: 1, sizePx: 256)
let pngBytes = try qr.imagePng(sizePx: 256) // [UInt8]
let svg = try qr.svg(sizePx: 256) // String
qr.close()
// 1D barcode. format: 0=Code128 1=Code39 2=EAN13 3=EAN8 4=UPCA 5=ITF 6=Code93 7=Codabar.
let bc = try BarcodeImage.generateBarcode("5901234123457", format: 2, sizePx: 256)
let barcodePng = try bc.imagePng(sizePx: 256)
bc.close()
Go(GenerateQRCode、GenerateBarcode):
package main
import (
"os"
pdfoxide "github.com/yfedoseev/pdf_oxide/go"
)
func main() {
// QR code. errorCorrection: 0=Low 1=Medium 2=Quartile 3=High.
qr, err := pdfoxide.GenerateQRCode("https://example.com", 1, 256)
if err != nil {
panic(err)
}
defer qr.Close()
svg, _ := qr.SVGData()
_ = os.WriteFile("qr.svg", []byte(svg), 0o644)
// 1D barcode. format: 0=Code128 1=Code39 2=EAN13 3=EAN8 4=UPCA 5=ITF 6=Code93 7=Codabar.
bc, err := pdfoxide.GenerateBarcode("5901234123457", 2, 300)
if err != nil {
panic(err)
}
defer bc.Close()
png, _ := bc.PNGData()
_ = os.WriteFile("ean13.png", png, 0o644)
}
C#(Barcode.GenerateQrCode、Barcode.Generate):
using PdfOxide;
// QR code. errorCorrection: 0=L 1=M 2=Q 3=H. sizePx default 300.
using var qr = Barcode.GenerateQrCode("https://example.com", errorCorrection: 1, sizePx: 256);
byte[] qrPng = qr.ToPng(256);
string qrSvg = qr.ToSvg();
// 1D barcode. BarcodeFormat: Code128, Code39, Ean13, Ean8, UpcA, Itf.
using var bc = Barcode.Generate("5901234123457", BarcodeFormat.Ean13, sizePx: 300);
byte[] eanPng = bc.ToPng(300);
Python(generate_qr_svg、generate_barcode_svg —— 仅 SVG):
import pdf_oxide
# QR code SVG. error_correction: 0=Low, 1=Medium, 2=Quartile, 3=High. size in px.
qr_svg = pdf_oxide.generate_qr_svg("https://example.com", 1, 256)
with open("qr.svg", "w") as f:
f.write(qr_svg)
# 1D barcode SVG. barcode_type: 0=Code128, 1=Code39, 2=EAN13, 3=EAN8,
# 4=UPCA, 5=ITF, 6=Code93, 7=Codabar.
ean_svg = pdf_oxide.generate_barcode_svg(2, "5901234123457")
with open("ean13.svg", "w") as f:
f.write(ean_svg)
如何向现有 PDF 页面添加条形码?
使用 add_barcode_to_page 可以将生成的条形码图像按给定位置和尺寸放置到 DocumentEditor 的某个(从 0 开始计数的)页面上,然后保存。它在 Swift 中以惯用方式公开为 DocumentEditor.addBarcodeToPage,并通过 C ABI 直接公开为 pdf_add_barcode_to_page。它所依赖的图像句柄家族并未被包装到 Go/C# 的编辑器类上,因此就地放置请使用 Swift(或从 C/C++ 调用 C ABI)。
Swift(DocumentEditor.addBarcodeToPage):
import PdfOxide
let editor = try DocumentEditor.openFromBytes(try Data(contentsOf: inputURL).map { $0 })
// Generate the barcode image, then stamp it onto page 0 (PDF user-space points).
let qr = try BarcodeImage.generateQrCode("https://example.com/track/42", sizePx: 128)
try editor.addBarcodeToPage(0, qr, x: 36, y: 36, width: 96, height: 96)
let outBytes = try editor.saveToBytes()
qr.close()
editor.close()
C ABI(pdf_add_barcode_to_page):
#include "pdf_oxide.h"
int err = 0;
// Build a barcode handle (QR shown; use pdf_generate_barcode for 1D).
FfiBarcodeImage *qr = pdf_generate_qr_code("https://example.com/track/42",
/*error_correction=*/1,
/*size_px=*/128, &err);
// Place it on page 0 at (x, y) sized width x height (PDF user-space points).
pdf_add_barcode_to_page(editor, /*page_index=*/0, qr,
/*x=*/36.0f, /*y=*/36.0f,
/*width=*/96.0f, /*height=*/96.0f, &err);
pdf_barcode_free(qr);
方法签名
一次性 PDF 构造器 —— 仅 Rust
// QR code, 300px default size:
Pdf::from_qrcode(data: &str) -> Result<Pdf>
Pdf::from_qrcode_with_options(data: &str, options: &QrCodeOptions) -> Result<Pdf>
// 1D barcode, 200x80 default size:
Pdf::from_barcode(barcode_type: BarcodeType, data: &str) -> Result<Pdf>
Pdf::from_barcode_with_options(barcode_type: BarcodeType, data: &str,
options: &BarcodeOptions) -> Result<Pdf>
条形码图像句柄家族 —— Swift / Go / C# / C ABI
| 语言 | 二维码生成器 | 一维码生成器 | 放置到页面 |
|---|---|---|---|
| Swift | BarcodeImage.generateQrCode(_ data:, errorCorrection: Int32 = 1, sizePx: Int32 = 256) |
BarcodeImage.generateBarcode(_ data:, format: Int32, sizePx: Int32 = 256) |
DocumentEditor.addBarcodeToPage(_ page:, _ barcode:, x:, y:, width:, height:) |
| Go | GenerateQRCode(data string, errorCorrection int, sizePx int) (*BarcodeImage, error) |
GenerateBarcode(data string, format int, sizePx int) (*BarcodeImage, error) |
——(未包装到编辑器上) |
| C# | Barcode.GenerateQrCode(string data, int errorCorrection = 1, int sizePx = 300) |
Barcode.Generate(string data, BarcodeFormat format = Code128, int sizePx = 300) |
——(未包装到编辑器上) |
| C ABI | pdf_generate_qr_code(const char *data, int32_t error_correction, int32_t size_px, int32_t *error_code) |
pdf_generate_barcode(const char *data, int32_t format, int32_t size_px, int32_t *error_code) |
pdf_add_barcode_to_page(DocumentEditor *doc, int32_t page_index, const FfiBarcodeImage *barcode, float x, float y, float width, float height, int32_t *error_code) |
一旦持有条形码句柄,你就可以读取其载荷并进行渲染:
| 操作 | Swift | Go | C# | C ABI |
|---|---|---|---|---|
| PNG 字节 | imagePng(sizePx:) |
PNGData() |
ToPng(sizePx) |
pdf_barcode_get_image_png |
| SVG 字符串 | svg(sizePx:) |
SVGData() |
ToSvg() |
pdf_barcode_get_svg |
| 解码后的数据 | data() |
SourceData() |
Data |
pdf_barcode_get_data |
| 格式代码 | format() |
— | Format |
pdf_barcode_get_format |
| 释放句柄 | close() |
Close() |
Dispose() |
pdf_barcode_free |
SVG 生成器 —— Python / Rust
# Python free functions (require the barcodes feature in the wheel):
generate_qr_svg(data: str, error_correction: int, size: int) -> str
generate_barcode_svg(barcode_type: int, data: str) -> str
Rust:完整 API 参考
二维码生成
Pdf::from_qrcode(data) —— 默认二维码
创建一个包含 300px 二维码的单页 PDF。
use pdf_oxide::api::Pdf;
let pdf = Pdf::from_qrcode("https://example.com")?;
pdf.save("qr.pdf")?;
Pdf::from_qrcode_with_options(data, options) —— 自定义二维码
完全控制尺寸、纠错、颜色和静默区。
use pdf_oxide::api::Pdf;
use pdf_oxide::writer::barcode::{QrCodeOptions, QrErrorCorrection};
let options = QrCodeOptions::new()
.size(400)
.error_correction(QrErrorCorrection::High)
.quiet_zone(6)
.foreground(0, 0, 128, 255) // Navy blue
.background(255, 255, 255, 255); // White
let pdf = Pdf::from_qrcode_with_options("https://example.com", &options)?;
pdf.save("custom_qr.pdf")?;
QrCodeOptions —— 二维码配置
| 方法 | 默认值 | 说明 |
|---|---|---|
.size(px) |
200 | 二维码尺寸(像素) |
.error_correction(level) |
Medium |
纠错级别 |
.quiet_zone(modules) |
4 | 以模块为单位的边框宽度 |
.foreground(r, g, b, a) |
Black (0,0,0,255) | 模块颜色(RGBA) |
.background(r, g, b, a) |
White (255,255,255,255) | 背景颜色(RGBA) |
QrErrorCorrection 枚举
| 变体 | 恢复能力 | 适用场景 | 整数(FFI) |
|---|---|---|---|
Low |
约 7% | 最大数据密度 | 0 |
Medium |
约 15% | 通用(默认) | 1 |
Quartile |
约 25% | 可能受损的标签 | 2 |
High |
约 30% | 工业/恶劣环境 | 3 |
一维条形码生成
Pdf::from_barcode(barcode_type, data) —— 默认条形码
使用默认尺寸(200x80)创建一个包含条形码的单页 PDF。
use pdf_oxide::api::Pdf;
use pdf_oxide::writer::barcode::BarcodeType;
let pdf = Pdf::from_barcode(BarcodeType::Ean13, "5901234123457")?;
pdf.save("product.pdf")?;
Pdf::from_barcode_with_options(barcode_type, data, options) —— 自定义条形码
完全控制条形码的尺寸和颜色。
use pdf_oxide::api::Pdf;
use pdf_oxide::writer::barcode::{BarcodeType, BarcodeOptions};
let options = BarcodeOptions::new()
.width(400)
.height(120)
.foreground(0, 0, 0, 255)
.background(255, 255, 255, 255);
let pdf = Pdf::from_barcode_with_options(
BarcodeType::Code128,
"SHIP-2025-00042",
&options,
)?;
pdf.save("shipping_label.pdf")?;
BarcodeOptions —— 一维码配置
| 方法 | 默认值 | 说明 |
|---|---|---|
.width(px) |
200 | 条形码宽度(像素) |
.height(px) |
80 | 条形码高度(像素) |
.foreground(r, g, b, a) |
Black (0,0,0,255) | 条纹颜色(RGBA) |
.background(r, g, b, a) |
White (255,255,255,255) | 背景颜色(RGBA) |
.show_text(bool) |
false | 显示人类可读文本 |
BarcodeType 枚举
| 变体 | 名称 | 数据格式 | 整数(FFI) |
|---|---|---|---|
Code128 |
Code 128 | 字母数字(自动选择 A/B/C) | 0 |
Code39 |
Code 39 | 大写字母数字 + 符号 | 1 |
Ean13 |
EAN-13 | 13 位数字(European Article Number) | 2 |
Ean8 |
EAN-8 | 8 位数字(紧凑型 EAN) | 3 |
UpcA |
UPC-A | 11–12 位数字(Universal Product Code) | 4 |
Itf |
Interleaved 2 of 5 | 数字对(位数为偶数) | 5 |
Code93 |
Code 93 | 字母数字(紧凑) | 6 |
Codabar |
Codabar | 数字 + 特殊字符(A-D 起止符) | 7 |
C ABI 的
pdf_generate_barcode以及 Go/Swift/C# 的封装通过上表的 整数(FFI) 列来选择符号体系。C# 的BarcodeFormat枚举目前公开了Code128–Itf(0–5)。
底层 BarcodeGenerator —— 仅 Rust
用于在不创建完整 PDF 的情况下生成条形码图像(例如,嵌入到现有文档中):
use pdf_oxide::writer::barcode::{BarcodeGenerator, BarcodeType, BarcodeOptions, QrCodeOptions};
// Generate QR code as PNG bytes
let qr_png = BarcodeGenerator::generate_qr(
"https://example.com",
&QrCodeOptions::default().size(256),
)?;
// Generate QR code as an SVG string
let qr_svg = BarcodeGenerator::generate_qr_svg(
"https://example.com",
&QrCodeOptions::default().size(256),
)?;
// Generate QR code with simple API
let qr_png = BarcodeGenerator::generate_qr_simple("https://example.com", 200)?;
// Generate 1D barcode as PNG bytes
let barcode_png = BarcodeGenerator::generate_1d(
BarcodeType::Code128,
"ABC123",
&BarcodeOptions::default().width(300).height(100),
)?;
// Generate 1D barcode as an SVG string
let barcode_svg = BarcodeGenerator::generate_1d_svg(
BarcodeType::Code128,
"ABC123",
&BarcodeOptions::default(),
)?;
// Convenience methods
let code128_png = BarcodeGenerator::generate_code128("DATA", 200, 80)?;
let ean13_png = BarcodeGenerator::generate_ean13("5901234123457", 200, 80)?;
在条形码中使用 PdfBuilder —— 仅 Rust
PdfBuilder 提供了一个流式接口,可在生成条形码 PDF 之前设置页面尺寸和文档元数据。
use pdf_oxide::api::PdfBuilder;
use pdf_oxide::writer::PageSize;
use pdf_oxide::writer::barcode::BarcodeType;
// QR code with custom page size
let pdf = PdfBuilder::new()
.title("WiFi Access")
.page_size(PageSize::Custom(300.0, 300.0))
.from_qrcode("WIFI:T:WPA;S:MyNetwork;P:secret123;;")?;
pdf.save("wifi_qr.pdf")?;
// Barcode with metadata
let pdf = PdfBuilder::new()
.title("Product Label")
.author("Warehouse System")
.from_barcode(BarcodeType::Ean13, "5901234123457")?;
pdf.save("label.pdf")?;
进阶示例
包含多个条形码的运输标签(Rust)
use pdf_oxide::writer::barcode::{BarcodeGenerator, QrCodeOptions, QrErrorCorrection};
// Generate barcode images, then embed via the image APIs.
let tracking_barcode = BarcodeGenerator::generate_code128(
"1Z999AA10123456784",
300,
80,
)?;
let qr_bytes = BarcodeGenerator::generate_qr(
"https://track.example.com/1Z999AA10123456784",
&QrCodeOptions::new().size(200).error_correction(QrErrorCorrection::Medium),
)?;
// `tracking_barcode` and `qr_bytes` are PNG byte vectors ready to embed.
批量生成产品标签(Rust)
use pdf_oxide::api::Pdf;
use pdf_oxide::writer::barcode::BarcodeType;
let products = vec![
("5901234123457", "Widget A"),
("4006381333931", "Widget B"),
("0012345678905", "Widget C"),
];
for (ean, name) in products {
let pdf = Pdf::from_barcode(BarcodeType::Ean13, ean)?;
pdf.save(format!("label_{}.pdf", name.to_lowercase().replace(' ', "_")))?;
}
批量生成条形码 SVG(Python)
import pdf_oxide
items = [
(0, "SHIP-00001"), # Code128
(0, "SHIP-00002"), # Code128
(2, "5901234123457"), # EAN-13
(4, "012345678905"), # UPC-A
]
for barcode_type, data in items:
svg = pdf_oxide.generate_barcode_svg(barcode_type, data)
with open(f"barcode_{data}.svg", "w") as f:
f.write(svg)
将追踪二维码盖印到每个标签上(Swift)
import PdfOxide
let editor = try DocumentEditor.openFromBytes(labelTemplateBytes)
let pageCount = try editor.pageCount()
for page in 0..<pageCount {
let qr = try BarcodeImage.generateQrCode("https://track.example.com/\(page)", sizePx: 128)
try editor.addBarcodeToPage(page, qr, x: 420, y: 700, width: 80, height: 80)
qr.close()
}
let stamped = try editor.saveToBytes()
editor.close()
特性标志
barcodes 特性会引入两个额外的依赖:
barcoders—— 一维条形码编码qrcode—— 二维码编码
如果不启用该特性标志,所有条形码方法都会返回一个错误,提示需要该特性。
// Without the barcodes feature enabled:
let result = Pdf::from_qrcode("test");
// Returns Err("QR code generation requires the 'barcodes' feature")
常见问题
问:文档提到了 generate_qr 和 generate_code——它们是正确的名称吗?
答:不是。规范的公开方法名是 generate_qr_code 和 generate_barcode(由 C ABI 的 pdf_generate_qr_code / pdf_generate_barcode 支撑)。在 Rust 内部,BarcodeGenerator 上的底层辅助方法是 generate_qr 和 generate_1d;它们是 Rust 内部的辅助方法,并非跨绑定的公共接口。
问:我能从 Python 或 Node 生成原生条形码吗?
答:Python 公开了 generate_qr_svg 和 generate_barcode_svg,它们返回可供嵌入或栅格化的 SVG 字符串。若需要 PNG 句柄和就地页面放置,请使用 Swift、Go 或 C# 绑定,或直接调用 C ABI。原生的一次性 PDF 构造器(from_qrcode / from_barcode)仅限 Rust。
问:如何在现有 PDF 中将条形码放置到特定位置?
答:先生成图像句柄(generate_qr_code / generate_barcode),然后调用 add_barcode_to_page(document, page_index, barcode, x, y, width, height)。坐标和尺寸以 PDF 用户空间点为单位,页面索引从 0 开始。它在 Swift 中被封装为 DocumentEditor.addBarcodeToPage;从 C/C++ 调用 pdf_add_barcode_to_page。
问:生成速度有多快? 答:pdf_oxide 的写入器构建在同一引擎之上,该引擎在基准语料库上以 0.8ms 平均耗时和 100% 通过率提取文本,因此编码一个二维码或一维条形码并输出一个页面,对批量工作负载而言几乎是瞬时完成的。
相关页面
- PdfBuilder 流式 API —— 为条形码 PDF 配置页面尺寸和元数据
- 从图像创建 —— 在多内容 PDF 中嵌入条形码 PNG
- 图形、图案与渐变 —— 用于自定义标签布局的底层绘制
- 类型与枚举 ——
BarcodeType枚举详情