下面我将为你详细介绍如何在 C 语言中使用最流行的开源库 libqrencode 来生成 QR 码,并介绍一个用于解析 QR 码的库 ZBar。

第一部分:生成 QR 码 (使用 libqrencode)
libqrencode 是一个非常成熟的 C 语言库,专门用于将文本数据编码成 QR 码的各种格式(如 PNG, SVG, EPS 等)。
安装 libqrencode
在 Linux (如 Ubuntu/Debian) 系统上,使用包管理器安装非常方便:
sudo apt-get update sudo apt-get install libqrencode-dev
这个包会安装库文件、头文件以及一些命令行工具(如 qrencode)。
在 macOS 上,可以使用 Homebrew:

brew install qrencode
在 Windows 上,你需要从源码编译或寻找预编译的库,这个过程相对复杂,建议使用 MSYS2 或 MinGW-w64 环境。
编写 C 代码
下面是一个简单的 C 程序,它将一段文本编码成 PNG 格式的 QR 码图片。
文件名: generate_qr.c
#include <stdio.h>
#include <stdlib.h>
#include <qrencode.h> // 引入 libqrencode 的头文件
// 函数:将 QR 码数据输出为 PNG 文件
// 参数:
// - text: 要编码的文本
// - filename: 输出的 PNG 文件名
// - version: QR 码版本 (1-40), 0 表示自动选择
// - size: 每个模块(黑白小方块)的大小(像素)
void generate_png_qr(const char *text, const char *filename, int version, int size) {
// QRcode_encodeString 函数将文本编码成 QR 码
// 参数:
// - version: QR 码版本 (1-40), 0 表示自动选择
// - level: 纠错等级 (QR_ECLEVEL_L, M, Q, H)
// - hint: 编码模式 (QR_MODE_8 for 8-bit data)
// - casesensitive: 是否区分大小写 (1 for yes, 0 for no)
QRcode *qrcode = QRcode_encodeString(text, version, QR_ECLEVEL_M, QR_MODE_8, 1);
if (qrcode == NULL) {
fprintf(stderr, "Error: Failed to generate QR code.\n");
return;
}
// 打开文件用于写入
FILE *fp = fopen(filename, "wb");
if (fp == NULL) {
fprintf(stderr, "Error: Could not create file %s\n", filename);
QRcode_free(qrcode); // 释放 QR 码内存
return;
}
// 使用 libqrencode 提供的辅助函数直接写入 PNG 文件
// 这是最简单的方法
QRcode_print PNG(qrcode, fp);
// 关闭文件和释放内存
fclose(fp);
QRcode_free(qrcode);
printf("QR Code successfully generated and saved to %s\n", filename);
}
int main() {
const char *text_to_encode = "Hello, C World! This is a QR code.";
const char *output_filename = "hello_qr.png";
// 自动选择版本,模块大小为 4 像素
generate_png_qr(text_to_encode, output_filename, 0, 4);
return 0;
}
编译和运行
使用 gcc 编译程序,并链接 libqrencode 库。

# -o 指定输出文件名 # -lqrencode 链接 libqrencode 库 # -lpng 链接 libpng 库,因为 PNG 输出需要它 gcc generate_qr.c -o generate_qr -lqrencode -lpng
运行生成的可执行文件:
./generate_qr
如果一切顺利,你会在当前目录下看到一个名为 hello_qr.png 的文件,用手机或任何 QR 码扫描器扫描它,都会显示 "Hello, C World! This is a QR code."。
第二部分:解析 QR 码 (使用 ZBar)
生成 QR 码后,你可能还需要解析它。ZBar 是一个强大的开源库,可以扫描和解码一维码和二维码。
安装 ZBar
在 Linux (Ubuntu/Debian) 上:
sudo apt-get install libzbar-dev zbar-tools
zbar-tools 包含了命令行工具 zbarimg,可以方便地从图片中扫描 QR 码。
在 macOS 上:
brew install zbar
编写 C 代码
ZBar 的 API 主要用于从视频流或图像中获取数据,这里我们展示如何从一个图片文件中解析 QR 码。
文件名: parse_qr.c
#include <stdio.h>
#include <zbar.h> // 引入 ZBar 的头文件
#ifdef ZBAR_HAVE_QRCODE
// ZBar 默认可能不包含 QR 码支持,需要确保编译时开启了它
// 在较新版本中通常是默认支持的
// 图像回调函数,当 ZBar 扫描到条码时会调用此函数
void image_handler(zbar_image_t *image, const void *userdata) {
// 获取图像中找到的符号数量
int count = zbar_image_get_symbols(image);
zbar_symbol_iterator_t *symbol = zbar_image_first_symbol(image);
for (; symbol != NULL; zbar_symbol_iterator_next(symbol)) {
zbar_symbol_type_t typ = zbar_symbol_get_type(symbol);
// 我们只关心 QR 码
if (zbar_get_symbol_name(typ) == ZBAR_NONE) {
continue;
}
const char *data = zbar_symbol_get_data(symbol);
printf("Decoded QR Code: %s\n", data);
}
}
int main() {
// 我们刚才生成的图片文件名
const char *filename = "hello_qr.png";
// 创建 ZBar 图像扫描器
zbar_image_scanner_t *scanner = zbar_image_scanner_create();
// 配置扫描器以启用 QR 码解码
zbar_image_scanner_set_config(scanner, ZBAR_QRCODE, ZBAR_CFG_ENABLE, 1);
// 创建一个 ZBar 图像对象
zbar_image_t *image = zbar_image_create();
// 从文件加载图像
// 注意:ZBar 需要一个原始的图像数据缓冲区,而不是像 libpng 这样的高阶库。
// 对于简单的 PNG,我们可以使用 stb_image 等库加载。
// 为了简化,这里我们假设图像是已经加载到内存中的。
// 在实际应用中,你需要使用图像加载库(如 stb_image, OpenCV, GD 等)。
// 这里我们使用一个简化的方法,假设我们有一个函数可以加载图像数据。
// --- 简化处理 ---
// 在实际项目中,你需要用 stb_image.h 等库加载图像到 buffer
// 这里我们只展示 ZBar 的核心逻辑,假装图像已经加载好了
// 为了演示,我们创建一个空的图像对象,并设置一些基本属性
// 你需要根据实际情况填充 width, height, data_buffer 等信息
// 这是一个占位符,你需要用真实的图像数据替换它
// 使用 stb_image.h 加载 PNG:
// int width, height, channels;
// unsigned char *img_data = stbi_load(filename, &width, &height, &channels, 0);
// if(!img_data) { /* 错误处理 */ }
// zbar_image_set_format(image, *(int*)"Y800"); // 灰度格式
// zbar_image_set_size(image, width, height);
// zbar_image_set_data(image, img_data, width * height, zbar_image_free_data);
// 为了演示,我们直接使用命令行工具 zbarimg
// 它更简单,适合快速测试
printf("Please use the command line tool for parsing:\n");
printf(" zbarimg %s\n", filename);
printf("Or, to see the output without opening a GUI:\n");
printf(" zbarimg --quiet %s\n", filename);
// ZBar 的 C API 直接解析文件比较麻烦,通常需要结合图像加载库。
// 下面是伪代码,展示了如果有了图像数据该如何处理:
/*
// 1. 加载图像数据 (例如使用 stb_image.h)
int width, height;
unsigned char *raw_data = load_image_from_file(filename, &width, &height);
// 2. 设置 ZBar 图像
zbar_image_set_format(image, *(int*)"Y800"); // 假设是灰度图
zbar_image_set_size(image, width, height);
zbar_image_set_data(image, raw_data, width * height, zbar_image_free_data);
// 3. 扫描图像
int result = zbar_scan_image(scanner, image);
// 4. 处理结果
if (result > 0) {
printf("Found %d barcode(s).\n", result);
image_handler(image, NULL);
} else {
printf("No barcode found.\n");
}
// 5. 释放资源
zbar_image_destroy(image);
zbar_image_scanner_destroy(scanner);
*/
return 0;
}
#else
int main() {
printf("ZBar was not compiled with QR code support.\n");
return 1;
}
#endif
重要提示:直接用 C 语言解析图片文件比生成要复杂,因为你需要一个图像加载库(如 stb_image.h,一个单头文件的图像加载库)来将 PNG/JPEG 文件读入内存,然后将原始数据传递给 ZBar。
对于快速测试,使用 ZBar 自带的命令行工具 zbarimg 是最简单的方法:
# 扫描图片并显示结果(会弹出窗口) zbarimg hello_qr.png # 安静模式,只打印解码结果,不弹出窗口 zbarimg --quiet hello_qr.png
总结与建议
| 任务 | 推荐库 | 优点 | 缺点 |
|---|---|---|---|
| 生成 QR 码 | libqrencode | API 简单,直接支持输出为 PNG/SVG/EPS 等格式,非常成熟。 | 功能相对纯粹,仅用于生成。 |
| 解析 QR 码 | ZBar | 功能强大,支持多种条码格式,跨平台。 | C API 需要配合图像加载库使用,不如生成部分直接。 |
给你的建议:
- 如果你想快速上手:直接使用
libqrencode生成 QR 码,然后用手机或电脑上的在线工具/软件来解析它,这是最简单的方式。 - 如果你想构建一个完整的 C 应用:
- 生成:使用
libqrencode,它的 API 非常直观。 - 解析:考虑引入
stb_image.h(非常轻量,只需一个.h文件)来加载图片,然后使用 ZBar 的 API 进行解码,或者,如果你不介意依赖,可以考虑使用 OpenCV,它集成了图像处理和 ZBar 的接口,功能更强大但也更复杂。
- 生成:使用
希望这个详细的指南能帮助你在 C 语言世界里玩转 QR 码!
