Zint生成二维码及png操作 Love The Way You Lie 2022-03-06 16:34 257阅读 0赞 1. [环境搭建点击查看][Link 1] 2. 编译demo * ubuntu下使用编译 > 连接动态库编译 > gcc -o demo demo.c zint\_code.c -lzint > 连接静态库编译 > gcc -o demo demo.c zint\_code.c -static -L. -lzint -lpng16 -lz -lm * arm-linux下使用编译 > a、把交叉编译链中的libz.a、libm.a拷贝到demo中 > b、执行编译命令 > arm-oe-linux-gnueabi-gcc -o demo demo.c zint\_code.c -static -L. -lzint -lz -lm 1. Zint生成二维码demo demo.c #include <stdio.h> #include "zint_code.h" int main(int argc, char *argv[]){ int ZintLibRet = 0; //ret code from zint lib ZINT_RET_CODE ZintRet = 0; //ret code from zint_code api char QrcodeData[] = "https://translate.google.cn/"; char QrcodeFile[] = "demo.png"; // Must end in .png, .eps or .svg. //zint lib ask ! //test with inputing qrcode_file name ZintRet = Zint_Create_QrCode((uint8_t*)QrcodeData, 0, QrcodeFile, &ZintLibRet); if(ZINT_OK != ZintRet){ Debuging("Create qrcode err, ZintRet = %d, ZintLibRet = %d\n", ZintRet, ZintLibRet); }else{ Debuging("Create qrcode OK ! View qrcode file : %s in cur path. ZintRet = %d, ZintLibRet = %d\n", QrcodeFile, ZintRet, ZintLibRet); } return 0; } zint\_code.c #include <string.h> #include <stdio.h> #include "zint.h" #include "zint_code.h" /**************************************************************************** Descpribe: Create Qrcode API with C Code by calling zint lib. Input : pQrCodeData, the qrcode data buf QrcodeLen, the len of qrcode data, but it can be 0 pQrCodeFile, the output file name of qrcode, it can be NULL Output : pZintRet, to store the ret code from linzint. Return : 0 is ok, and other values are fail. See the meanings in enum ZINT_RET_CODE Notes : pQrCodeFile, Must end in .png, .eps or .svg. when isn,t NULL string. ****************************************************************************/ ZINT_RET_CODE Zint_Create_QrCode(uint8_t *pQrCodeData, int QrcodeLen, char *pQrCodeFile, int *pZintRet){ struct zint_symbol *pMySymbol = NULL; int RetCode = 0; if(!pQrCodeData){ //check input pointer return ZINT_ERR_INV_DATA; } if(QrcodeLen == 0){ QrcodeLen = strlen((char *)pQrCodeData); } if(QrcodeLen > QRCODE_MAX_LEN){ //len is too long return ZINT_ERR_TOO_LONG; } if(0 == ZBarcode_ValidID(BARCODE_QRCODE)){ return ZINT_ERR_INV_CODE_ID; } pMySymbol = ZBarcode_Create(); if(pMySymbol == NULL){ return ZINT_ERR_MEMORY; } if(pQrCodeFile){ //when it's NULL, outfile will be "out.png" if(strstr(pQrCodeFile, "png") || (strstr(pQrCodeFile, "eps")) || (strstr(pQrCodeFile, "svg"))){ strcpy(pMySymbol->outfile, pQrCodeFile); }else{ ZBarcode_Clear(pMySymbol); ZBarcode_Delete(pMySymbol); //release memory in zint lib return ZINT_ERR_FILE_NAME; } } pMySymbol->symbology = BARCODE_QRCODE; pMySymbol->option_1 = 2; //ECC Level.It can be large when ECC Level is larger.(value:1-4) pMySymbol->scale = 1.2; //contorl qrcode file size, default is 1, used to be 4 pMySymbol->border_width = 1; //set white space width around your qrcode and 0 is for nothing #if 0 //生成png图片 RetCode = ZBarcode_Encode_and_Print(pMySymbol, pQrCodeData, QrcodeLen, 0); #else //获取bmp的rgb值 ZBarcode_Encode_and_Buffer(pMySymbol, pQrCodeData, QrcodeLen, 0); unsigned char r, g, b; int i = 0; for (int row = 0; row < pMySymbol->bitmap_height; ++row) { for (int col = 0; col < pMySymbol->bitmap_width; ++col) { r = pMySymbol->bitmap[i]; g = pMySymbol->bitmap[i + 1]; b = pMySymbol->bitmap[i + 2]; i += 3; if (r == 0 && g == 0 & b == 0){ printf("■"); } else { printf("□"); } } printf(" r:%d, g:%d, b:%d\n", r, g, b); } #endif ZBarcode_Clear(pMySymbol); ZBarcode_Delete(pMySymbol); //release memory in zint lib if(pZintRet){ *pZintRet = RetCode; //save ret code from zint lib } return ((0 == RetCode) ? (ZINT_OK) : (ZINT_ERR_LIB_RET)); } zint\_code.h #ifndef __ZINT_CODE__ #define __ZINT_CODE__ #ifdef __cplusplus extern "C" { #endif #include <stdint.h> #define QRCODE_MAX_LEN 500 //max string len for creating qrcode typedef enum { ZINT_OK = 0, ZINT_ERR_INV_DATA = -1, //input invalid data ZINT_ERR_TOO_LONG = -2, //len for input data is too long ZINT_ERR_INV_CODE_ID = -3,//the code type is not supported by zint ZINT_ERR_MEMORY = -4, //malloc memory error in zint lib ZINT_ERR_FILE_NAME = -5, //qrcode file isn'y end in .png, .eps or .svg. ZINT_ERR_LIB_RET = -6, //zint lib ret error, real ret code should be zint api ret code }ZINT_RET_CODE; /**************************************************************************** Descpribe: Create Qrcode API with C Code by calling zint lib. Input : pQrCodeData, the qrcode data buf QrcodeLen, the len of qrcode data, but it can be 0 pQrCodeFile, the output file name of qrcode, it can be NULL Output : pZintRet, to store the ret code from linzint. Return : 0 is ok, and other values are fail. See the meanings in enum ZINT_RET_CODE Notes : pQrCodeFile, Must end in .png, .eps or .svg. when isn,t NULL string. ****************************************************************************/ ZINT_RET_CODE Zint_Create_QrCode(uint8_t *pQrCodeData, int QrcodeLen, char *pQrCodeFile, int *pZintRet); #define Debuging(fmt, arg...) printf("[%20s, %4d] "fmt, __FILE__, __LINE__, ##arg) #ifdef __cplusplus } #endif #endif /* __ZINT_CODE__ */ 1. 读取png原始数据操作 read-png-data.c #include<stdio.h> #include<string.h> #include<malloc.h> #include<stdlib.h> #include<math.h> #define SAFE_FREE(x) {free(x);x=NULL;} #define BUFFER_SIZE 1024*1024 int main(){ unsigned int offset = 0; FILE* sFile = fopen("1.png", "rb"); FILE* dFile = fopen("d.txt", "w"); FILE* txtFile = fopen("t.txt", "w"); unsigned char* buf=(unsigned char*)malloc(BUFFER_SIZE); size_t nSize = fread(buf,1,BUFFER_SIZE, sFile); unsigned char png[]={0x89,0x50,0x4e,0x47,0xd,0xa,0x1a,0xa}; for(;offset<8;offset++){ if(buf[offset]!=png[offset]){ printf("no png\n"); return 0; } } while(offset<nSize){ unsigned int dataLen = 0; for(unsigned int i=offset+4;offset<i;offset++){ dataLen+=buf[offset]*pow((double)256, (int)(i-offset-1)); } if(buf[offset] == 'I' && buf[offset+1]=='D' &&buf[offset+2]=='A' &&buf[offset+3]=='T'){ int count = 0; for(int i=0;i<dataLen;i++){ fprintf(txtFile,"0x%x ",buf[offset+4+i]); count++; } printf("count:%d\n",count); fprintf(txtFile,"\n\n\n\n"); } for(char i=0;i<4;i++){ fprintf(dFile,"%c",buf[offset++]); } fprintf(dFile,"\n"); offset+=(dataLen+4); } fclose(sFile); fclose(dFile); fclose(txtFile); SAFE_FREE(buf); } 1. png的读写操作(获取rgb数据) png-read-write.c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <png.h> #define PNG_BYTES_TO_CHECK 8 #define HAVE_ALPHA 1 #define NOT_HAVE_ALPHA 0 typedef struct _pic_data pic_data; struct _pic_data { int width, height; //长宽 int bit_depth; //位深度 int alpha_flag; //是否有透明通道 unsigned char *rgba;//实际rgb数据 }; int check_is_png(FILE **fp, const char *filename) //检查是否png文件 { char checkheader[PNG_BYTES_TO_CHECK]; //查询是否png头 *fp = fopen(filename, "rb"); if (*fp == NULL) { printf("open failed ...1\n"); return -1; } if (fread(checkheader, 1, PNG_BYTES_TO_CHECK, *fp) != PNG_BYTES_TO_CHECK) //读取png文件长度错误直接退出 return 0; return png_sig_cmp(checkheader, 0, PNG_BYTES_TO_CHECK); //0正确, 非0错误 } int decode_png(const char *filename, pic_data *out) //取出png文件中的rgb数据 { png_structp png_ptr; //png文件句柄 png_infop info_ptr;//png图像信息句柄 int ret; FILE *fp; if (check_is_png(&fp, filename) != 0) { printf("file is not png ...\n"); return -1; } printf("launcher[%s] ...\n", PNG_LIBPNG_VER_STRING); //打印当前libpng版本号 //1: 初始化libpng的数据结构 :png_ptr, info_ptr png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); info_ptr = png_create_info_struct(png_ptr); //2: 设置错误的返回点 setjmp(png_jmpbuf(png_ptr)); rewind(fp); //等价fseek(fp, 0, SEEK_SET); //3: 把png结构体和文件流io进行绑定 png_init_io(png_ptr, fp); //4:读取png文件信息以及强转转换成RGBA:8888数据格式 png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_EXPAND, 0); //读取文件信息 int channels, color_type; channels = png_get_channels(png_ptr, info_ptr); //通道数量 color_type = png_get_color_type(png_ptr, info_ptr);//颜色类型 out->bit_depth = png_get_bit_depth(png_ptr, info_ptr);//位深度 out->width = png_get_image_width(png_ptr, info_ptr);//宽 out->height = png_get_image_height(png_ptr, info_ptr);//高 //if(color_type == PNG_COLOR_TYPE_PALETTE) // png_set_palette_to_rgb(png_ptr);//要求转换索引颜色到RGB //if(color_type == PNG_COLOR_TYPE_GRAY && out->bit_depth < 8) // png_set_expand_gray_1_2_4_to_8(png_ptr);//要求位深度强制8bit //if(out->bit_depth == 16) // png_set_strip_16(png_ptr);//要求位深度强制8bit //if(png_get_valid(png_ptr,info_ptr,PNG_INFO_tRNS)) // png_set_tRNS_to_alpha(png_ptr); //if(color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA) // png_set_gray_to_rgb(png_ptr);//灰度必须转换成RG printf("channels = %d color_type = %d bit_depth = %d width = %d height = %d ...\n", channels, color_type, out->bit_depth, out->width, out->height); int i, j, k; int size, pos = 0; int temp; //5: 读取实际的rgb数据 png_bytepp row_pointers; //实际存储rgb数据的buf row_pointers = png_get_rows(png_ptr, info_ptr); //也可以分别每一行获取png_get_rowbytes(); size = out->width * out->height; //申请内存先计算空间 if (channels == 4 || color_type == PNG_COLOR_TYPE_RGB_ALPHA) { //判断是24位还是32位 out->alpha_flag = HAVE_ALPHA; //记录是否有透明通道 size *= (sizeof(unsigned char) * 4); //size = out->width * out->height * channel out->rgba = (png_bytep)malloc(size); if (NULL == out->rgba) { printf("malloc rgba faile ...\n"); png_destroy_read_struct(&png_ptr, &info_ptr, 0); fclose(fp); return -1; } //从row_pointers里读出实际的rgb数据出来 temp = channels - 1; for (i = 0; i < out->height; i++) for (j = 0; j < out->width * 4; j += 4) for (k = temp; k >= 0; k--) out->rgba[pos++] = row_pointers[i][j + k]; } else if (channels == 3 || color_type == PNG_COLOR_TYPE_RGB) { //判断颜色深度是24位还是32位 out->alpha_flag = NOT_HAVE_ALPHA; size *= (sizeof(unsigned char) * 3); out->rgba = (png_bytep)malloc(size); if (NULL == out->rgba) { printf("malloc rgba faile ...\n"); png_destroy_read_struct(&png_ptr, &info_ptr, 0); fclose(fp); return -1; } //从row_pointers里读出实际的rgb数据 temp = (3 * out->width); for (i = 0; i < out->height; i ++) { for (j = 0; j < temp; j += 3) { out->rgba[pos++] = row_pointers[i][j+2]; out->rgba[pos++] = row_pointers[i][j+1]; out->rgba[pos++] = row_pointers[i][j+0]; } } } else return -1; //6:销毁内存 png_destroy_read_struct(&png_ptr, &info_ptr, 0); fclose(fp); //此时, 我们的out->rgba里面已经存储有实际的rgb数据了 //处理完成以后free(out->rgba) return 0; } int RotationRight90(unsigned char * src, int srcW, int srcH, int channel) //顺时针旋转90度 { unsigned char * tempSrc = NULL; //临时的buf用来记录原始的图像(未旋转之前的图像) int mSize = srcW * srcH * sizeof(char) * channel; int i = 0; int j = 0; int k = 0; int l = 3; int desW = 0; int desH = 0; desW = srcH; desH = srcW; tempSrc = (unsigned char *)malloc(sizeof(char) * srcW * srcH * channel); memcpy(tempSrc, src, mSize); //拷贝原始图像至tempbuf for(i = 0; i < desH; i ++) { for(j = 0; j < desW; j ++) { for(k = 0; k < channel; k ++) { src[(i * desW + j) * channel + k] = tempSrc[((srcH - 1 - j) * srcW + i) * channel + k]; //替换像素 } } } free(tempSrc); return 0; } int write_png_file(const char *filename , pic_data *out) //生成一个新的png图像 { png_structp png_ptr; png_infop info_ptr; png_byte color_type; png_bytep * row_pointers; FILE *fp = fopen(filename, "wb"); if (NULL == fp) { printf("open failed ...2\n"); return -1; } //1: 初始化libpng结构体 png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0); if (!png_ptr) { printf("png_create_write_struct failed ...\n"); return -1; } //2: 初始化png_infop结构体 , //此结构体包含了图像的各种信息如尺寸,像素位深, 颜色类型等等 info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) { printf("png_create_info_struct failed ...\n"); return -1; } //3: 设置错误返回点 if (setjmp(png_jmpbuf(png_ptr))) { printf("error during init_io ...\n"); return -1; } //4:绑定文件IO到Png结构体 png_init_io(png_ptr, fp); if (setjmp(png_jmpbuf(png_ptr))) { printf("error during init_io ...\n"); return -1; } if (out->alpha_flag == HAVE_ALPHA) color_type = PNG_COLOR_TYPE_RGB_ALPHA; else color_type = PNG_COLOR_TYPE_RGB; //5:设置以及写入头部信息到Png文件 png_set_IHDR(png_ptr, info_ptr, out->width, out->height, out->bit_depth, color_type, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); png_write_info(png_ptr, info_ptr); if (setjmp(png_jmpbuf(png_ptr))) { printf("error during init_io ...\n"); return -1; } int channels, temp; int i, j, pos = 0; if (out->alpha_flag == HAVE_ALPHA) { channels = 4; temp = (4 * out->width); printf("have alpha ...\n"); } else { channels = 3; temp = (3 * out->width); printf("not have alpha ...\n"); } // 顺时针旋转90度 , 旋转完了一定要把width 和height调换 不然得到的图像是花的 旋转三次就是逆时针旋转一次 //RotationRight90(out->rgba, out->width, out->height, channels); //RotationRight90(out->rgba, out->height, out->width, channels); //RotationRight90(out->rgba, out->width, out->height, channels); row_pointers = (png_bytep*)malloc(out->height * sizeof(png_bytep)); for (i = 0; i < out->height; i++) { row_pointers[i] = (png_bytep)malloc(temp* sizeof(unsigned char)); for (j = 0; j < temp; j += channels) { if (channels == 4) { row_pointers[i][j+3] = out->rgba[pos++]; row_pointers[i][j+2] = out->rgba[pos++]; row_pointers[i][j+1] = out->rgba[pos++]; row_pointers[i][j+0] = out->rgba[pos++]; } else { row_pointers[i][j+2] = out->rgba[pos++]; row_pointers[i][j+1] = out->rgba[pos++]; row_pointers[i][j+0] = out->rgba[pos++]; } } } //6: 写入rgb数据到Png文件 png_write_image(png_ptr, (png_bytepp)row_pointers); if (setjmp(png_jmpbuf(png_ptr))) { printf("error during init_io ...\n"); return -1; } //7: 写入尾部信息 png_write_end(png_ptr, NULL); //8:释放内存 ,销毁png结构体 for (i = 0; i < out->height; i ++) free(row_pointers[i]); free(row_pointers); png_destroy_write_struct(&png_ptr, &info_ptr); fclose(fp); return 0; } int main(int argc, char **argv) { pic_data out; decode_png("1.png", &out); write_png_file("2.png", &out); free(out.rgba); return 0; } 1. png的rgb转为565 rgb-to-565.c #include <stdio.h> int main(int argc, char *argv[]) { unsigned short R=0xFF; unsigned short G=0xFF; unsigned short B=0xFF; unsigned short buf = 0; #if 0 //swap != 0 /*Pixel format: Red: 5 bit, Green: 6 bit, Blue: 5 bit BUT the 2 color bytes are swapped*/ R = (R & 0XF8) << 8; buf = buf | R; printf("buf=%#x\n",buf); G = (G & 0X7E) << 4; buf = buf | G; printf("buf=%#x\n",buf); B = (B & 0X1F); buf = buf | B; printf("buf=%#x\n",buf); #else //swap /*Pixel format: Red: 5 bit, Green: 6 bit, Blue: 5 bit*/ unsigned short T = 0; R = (R & 0XF8) << 8; buf = buf | R; printf("buf=%#x\n",buf); G = (G & 0X7E) << 4; buf = buf | G; printf("buf=%#x\n",buf); B = (B & 0X1F); buf = buf | B; T = buf >> 8; buf = (buf << 8) | T; printf("buf=%#x\n",buf); #endif return 0; } [Link 1]: https://blog.csdn.net/hanbo622/article/details/88707399
相关 生成二维码 ,需要依赖: <dependency> <groupId>com.google.zxing</groupId> ... 不念不忘少年蓝@/ 2024年04月18日 16:19/ 0 赞/ 93 阅读
相关 生成二维码 引入依赖 <!-- https://mvnrepository.com/artifact/com.google.zxing/core --> 缺乏、安全感/ 2023年07月15日 12:52/ 0 赞/ 28 阅读
相关 生成二维码 相关博客:[统一返回结果][Link 1] 创建SpringBoot项目 <!-- 二维码生成 --> <dependency> <gr 傷城~/ 2022年10月20日 13:55/ 0 赞/ 358 阅读
相关 swift生成二维码,扫描二维码 ~~~写在前面的话~~~ 我之前打算做一个APP,然后把电话号码生成二维码 或者条形码, 用手机扫描,这样,就不用担心会输入错误电话号码了。 在下面是实现的扫描二维码的功能 墨蓝/ 2022年09月25日 13:19/ 0 赞/ 543 阅读
相关 生成二维码 一个命名空间 namespace BarCode \{ public static class TwoDimensionCode \{ 悠悠/ 2022年08月05日 01:17/ 0 赞/ 396 阅读
相关 生成二维码 文档: [http://blog.csdn.net/yuxmdef1/article/details/17793461][http_blog.csdn.net_yuxmdef1 男娘i/ 2022年06月13日 06:38/ 0 赞/ 409 阅读
相关 生成二维码 生成二维码 / 生成二维码(QRCode)图片的公共方法 @param content 存储内容 @param imgTyp 小鱼儿/ 2022年03月31日 05:10/ 0 赞/ 398 阅读
相关 Zint生成二维码及png操作 1. [环境搭建点击查看][Link 1] 2. 编译demo ubuntu下使用编译 > 连接动态库编译 > gcc -o demo demo.c zint Love The Way You Lie/ 2022年03月06日 16:34/ 0 赞/ 258 阅读
相关 Zint生成二维码环境搭建 1. 安装zint > mkdir build > cd build > cmake … > make \[-j nr\ 爱被打了一巴掌/ 2022年03月06日 15:46/ 0 赞/ 188 阅读
相关 二维码生成 maven依赖 <!-- 二维码 --> <dependency> <groupId>com.google.zxing</groupId> 悠悠/ 2021年12月10日 15:39/ 0 赞/ 540 阅读
还没有评论,来说两句吧...