一、需求
要将一段数据生成为二维码,
二、方案
使用linux标准库,通过libqrencode将需要写入的信息转为二维码图片数据。
三、实现
3.1编写c文件
#include <stdio.h>
#include <stdlib.h>
#include <qrencode.h>
int main() {
QRcode *qrcode;
unsigned char *data;
int version = 1;
int width = 256;
int margin = 2;
// 生成二维码数据
qrcode = QRcode_encodeString("Hello, world!", version, QR_ECLEVEL_L, QR_MODE_8, 1);
if (qrcode == NULL) {
fprintf(stderr, "Failed to encode string.\n");
return -1;
}
// 创建图像数据
data = (unsigned char *)malloc(qrcode->width * qrcode->width * 3);
if (data == NULL) {
fprintf(stderr, "Failed to allocate memory.\n");
QRcode_free(qrcode);
return -1;
}
// 将二维码数据转换为图像数据
for (int y = 0; y < qrcode->width; y++) {
for (int x = 0; x < qrcode->width; x++) {
int offset = (y * qrcode->width + x) * 3;
if (qrcode->data[y * qrcode->width + x] & 0x01) {
data[offset] = 0; // R
data[offset + 1] = 0; // G
data[offset + 2] = 0; // B
} else {
data[offset] = 255; // R
data[offset + 1] = 255; // G
data[offset + 2] = 255; // B
}
}
}
// 保存图像数据为PNG文件
FILE *fp = fopen("qrcode.png", "wb");
if (fp == NULL) {
fprintf(stderr, "Failed to open file.\n"); QRcode_free(qrcode);
free(data);
return -1;
}
fwrite(data, 1, qrcode->width * qrcode->width * 3, fp);
fclose(fp);
// 释放内存
QRcode_free(qrcode);
free(data);
printf("QR code generated and saved as qrcode.png.\n");
return 0;
}
3.2编译c文件为可执行文件
3.2.1第一次编译
Evenurs@admin-PowerEdge-S350-166:~/f1c100s/dev/f1c100s/tina$ /home/Evenurs/f1c100s/dev/f1c100s/tina/prebuilt/gcc/linux-x86/arm/toolchain-sunxi-arm9-musl/toolchain/bin/arm-openwrt-linux-muslgnueabi-gcc qrencode.c -o qrencode
报错:
arm-openwrt-linux-muslgnueabi-gcc.bin: warning: environment variable 'STAGING_DIR' not defined
qrencode.c:3:22: fatal error: qrencode.h: No such file or directory
^
compilation terminated.
分析:找不到qrencode.h头文件。
解决方法:编译时依赖库文件。
3.2.2第二次编译
Evenurs@admin-PowerEdge-S350-166:~/f1c100s/dev/f1c100s/tina$ /home/Evenurs/f1c100s/dev/f1c100s/tina/prebuilt/gcc/linux-x86/arm/toolchain-sunxi-arm9-musl/toolchain/bin/arm-openwrt-linux-muslgnueabi-gcc qrencode.c -o qrencode -lqrencode
报错:
arm-openwrt-linux-muslgnueabi-gcc.bin: warning: environment variable 'STAGING_DIR' not defined
qrencode.c:3:22: fatal error: qrencode.h: No such file or directory
^
compilation terminated.
分析:找不到库文件。
解决方法:需要指定头文件的路径。
3.2.3第三次编译
Evenurs@admin-PowerEdge-S350-166:~/f1c100s/dev/f1c100s/tina$ /home/Evenurs/f1c100s/dev/f1c100s/tina/prebuilt/gcc/linux-x86/arm/toolchain-sunxi-arm9-musl/toolchain/bin/arm-openwrt-linux-muslgnueabi-gcc -I /home/Evenurs/f1c100s/dev/f1c100s/tina/out/c200s-F1C200s/compile_dir/target/qrencode-3.4.4/ qrencode.c -o qrencode
报错:
arm-openwrt-linux-muslgnueabi-gcc.bin: warning: environment variable 'STAGING_DIR' not defined
arm-openwrt-linux-muslgnueabi-gcc.bin: warning: environment variable 'STAGING_DIR' not defined
arm-openwrt-linux-muslgnueabi-gcc.bin: warning: environment variable 'STAGING_DIR' not defined
/tmp/ccEgRQio.o: In function `main':
qrencode.c:(.text+0x3c): undefined reference to `QRcode_encodeString'
qrencode.c:(.text+0xc8): undefined reference to `QRcode_free'
qrencode.c:(.text+0x24c): undefined reference to `QRcode_free'
qrencode.c:(.text+0x2a0): undefined reference to `QRcode_free'
collect2: error: ld returned 1 exit status
分析:头文件已找到,库文件仍需要依赖。
解决方法:依赖库文件。
3.2.4第四次编译
Evenurs@admin-PowerEdge-S350-166:~/f1c100s/dev/f1c100s/tina$ /home/Evenurs/f1c100s/dev/f1c100s/tina/prebuilt/gcc/linux-x86/arm/toolchain-sunxi-arm9-musl/toolchain/bin/arm-openwrt-linux-muslgnueabi-gcc -I /home/Evenurs/f1c100s/dev/f1c100s/tina/out/c200s-F1C200s/compile_dir/target/qrencode-3.4.4/ qrencode.c -o qrencode -lqrencode
报错:
arm-openwrt-linux-muslgnueabi-gcc.bin: warning: environment variable 'STAGING_DIR' not defined
arm-openwrt-linux-muslgnueabi-gcc.bin: warning: environment variable 'STAGING_DIR' not defined
arm-openwrt-linux-muslgnueabi-gcc.bin: warning: environment variable 'STAGING_DIR' not defined
/home/Evenurs/f1c100s/dev/f1c100s/tina/prebuilt/gcc/linux-x86/arm/toolchain-sunxi-arm9-musl/toolchain/bin/../lib/gcc/arm-openwrt-linux-muslgnueabi/6.4.1/../../../../arm-openwrt-linux-muslgnueabi/bin/ld: cannot find -lqrencode
collect2: error: ld returned 1 exit status
分析:依然找不到库文件路径。
解决方法:在编译时指定寻找查找库文件的路径。
3.2.5第五次编译
Evenurs@admin-PowerEdge-S350-166:~/f1c100s/dev/f1c100s/tina$ /home/Evenurs/f1c100s/dev/f1c100s/tina/prebuilt/gcc/linux-x86/arm/toolchain-sunxi-arm9-musl/toolchain/bin/arm-openwrt-linux-muslgnueabi-gcc -I /home/Evenurs/f1c100s/dev/f1c100s/tina/out/c200s-F1C200s/compile_dir/target/qrencode-3.4.4/ qrencode.c -o qrencode -L /home/Evenurs/f1c100s/dev/f1c100s/tina/out/c200s-F1C200s/compile_dir/target/qrencode-3.4.4/.libs -lqrencode
编译通过:
arm-openwrt-linux-muslgnueabi-gcc.bin: warning: environment variable 'STAGING_DIR' not defined
arm-openwrt-linux-muslgnueabi-gcc.bin: warning: environment variable 'STAGING_DIR' not defined
arm-openwrt-linux-muslgnueabi-gcc.bin: warning: environment variable 'STAGING_DIR' not defined
3.3通过adb烧录
通过adb push的方法烧录,详细步骤可参考:
【adb】adb push命令 向设备传输文件https://evenurs.blog.csdn.net/article/details/128940198?spm=1001.2014.3001.5502
3.4运行
root@TinaLinux:/# chmod -R 777 ./qrencode
root@TinaLinux:/# ./qrencode
QR code generated and saved as qrcode.png.
root@TinaLinux:/# ls
bin lib pseudo_init rom tmp
dev mnt qrcode.png root usr
etc overlay qrencode sbin var
hello proc rdinit sys www
root@TinaLinux:/#
3.5将qrcode.png通过adb pull导出到电脑
查看数据:
确认是像素颜色数据,只是由于没有文件配置的头数据,会导致文件无法被打开与识别。
四、结论
通过libqrencode库,的确可以将数据转为二维码图片数据,图片数据转成图片则需要借助其他工具实现。