libpng+VS2012(VS2015)的使用
OpenCV保存PNG图像底层调用的就是libpng库,简要说一下libPNG库的单独使用。
1.首先需要下载两个库,一个是libpng,一个是zlib
libpng库下载地址:http://www.libpng.org/pub/png/libpng.html
zlib库下载地址:http://www.zlib.net/
2.将两个库下载后解压到同一个文件目录下,如图:
3. 打开libpng库文件目录:\lpng1632\projects\vstudio中,用记事本打开zlib.props配置文件,对应修改zlib库的版本并保存,如下图,我用的是zlib-1.2.11
4.打开同目录下的vstudio解决方案,然后直接在debug或者release模式编译,win32或者x64均可。我用VS2012编译没有任何异常,全部成功,VS2015出现一些错误提示,但是不影响lib库的生成.
5.编译后得到的lib库和dll文件分别在同目录的Debug和Release文件中,x64下编译会在x64文件中。我们需要的是其中的libpng16.lib,libpng16.dll和zlib.lib三个文件。
6.新建VS项目,VC++目录中的包含目录分别设置为libpng库和zlib库所在路径,库目录设置为刚刚生成的lib库所在目录,链接器->输入中将两个lib库名称添加进去,并将libpng16.dll放进工程的可执行文件目录中。(其实跟配置Opencv一样一样的)
以上配置完毕,可以调用libpng库中的接口API进行图像的读写操作了,可以参考libpng库目录中的example.c文件,里面有API的说明。具体的读写代码网上也都能找到。
我列出自己简单编写的写入png图像的代码,读入lena.jpg,保存为lena.png。代码如下,仅供参考。
1 #include <opencv2\opencv.hpp> 2 #include <stddef.h> 3 #include <stdlib.h> 4 #include <string.h> 5 #include <stdio.h> 6 #include <png.h> 7 #include <zlib.h> 8 9 using namespace cv; 10 11 int write_png_file(char *file_name , Mat srcImg, int imgW, int imgH, int channels) 12 { 13 uchar* pImgData=(uchar*)srcImg.data; 14 int j, i, temp, pos; 15 png_byte color_type; 16 17 png_structp png_ptr; 18 png_infop info_ptr; 19 png_bytep * row_pointers; 20 /* create file */ 21 FILE *fp = fopen(file_name, "wb"); 22 if (!fp) 23 { 24 printf("[write_png_file] File %s could not be opened for writing", file_name); 25 return -1; 26 } 27 28 /* initialize stuff */ 29 png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); 30 31 if (!png_ptr) 32 { 33 printf("[write_png_file] png_create_write_struct failed"); 34 return -1; 35 } 36 info_ptr = png_create_info_struct(png_ptr); 37 if (!info_ptr) 38 { 39 printf("[write_png_file] png_create_info_struct failed"); 40 return -1; 41 } 42 if (setjmp(png_jmpbuf(png_ptr))) 43 { 44 printf("[write_png_file] Error during init_io"); 45 return -1; 46 } 47 png_init_io(png_ptr, fp); 48 49 /* write header */ 50 if (setjmp(png_jmpbuf(png_ptr))) 51 { 52 printf("[write_png_file] Error during writing header"); 53 return -1; 54 } 55 /* 判断要写入至文件的图片数据是否有透明度,来选择色彩类型 */ 56 if(channels == 4) 57 { 58 color_type = PNG_COLOR_TYPE_RGB_ALPHA; 59 } 60 else if(channels==1) 61 { 62 color_type = PNG_COLOR_TYPE_GRAY; 63 } 64 else 65 { 66 color_type = PNG_COLOR_TYPE_RGB; 67 } 68 69 png_set_IHDR(png_ptr, info_ptr, imgW, imgH, 70 8, color_type, PNG_INTERLACE_NONE, 71 PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); 72 73 png_write_info(png_ptr, info_ptr); 74 75 /* write bytes */ 76 if (setjmp(png_jmpbuf(png_ptr))) 77 { 78 printf("[write_png_file] Error during writing bytes"); 79 return -1; 80 } 81 if(channels == 4) 82 { 83 temp = (4 * imgW); 84 } 85 else if(channels == 1) 86 { 87 temp = ( imgW); 88 } 89 else 90 { 91 temp = ( 3*imgW); 92 } 93 94 row_pointers = (png_bytep*)malloc(imgH*sizeof(png_bytep)); 95 for(i = 0; i < imgH; i++) 96 { 97 row_pointers[i] = (png_bytep)malloc(sizeof(uchar)*temp); 98 for(j = 0; j < imgW; j += 1) 99 { 100 if(channels==4) 101 { 102 row_pointers[i][j*3+0] = pImgData[i*imgW*3+ j*3+0]; // blue 103 row_pointers[i][j*3+1] = pImgData[i*imgW*3+ j*3+1]; // green 104 row_pointers[i][j*3+2] = pImgData[i*imgW*3+ j*3+2]; // red 105 row_pointers[i][j*3+3] = pImgData[i*imgW*3+ j*3+3]; // alpha 106 } 107 else if(channels==1) 108 { 109 row_pointers[i][j] = pImgData[i*imgW+ j]; // gray 110 } 111 else 112 { 113 row_pointers[i][j*3+0] = pImgData[i*imgW*3+ j*3+0]; // blue 114 row_pointers[i][j*3+1] = pImgData[i*imgW*3+ j*3+1]; // green 115 row_pointers[i][j*3+2] = pImgData[i*imgW*3+ j*3+2]; // red 116 } 117 } 118 } 119 png_write_image(png_ptr, row_pointers); 120 121 /* end write */ 122 if (setjmp(png_jmpbuf(png_ptr))) 123 { 124 printf("[write_png_file] Error during end of write"); 125 return -1; 126 } 127 png_write_end(png_ptr, NULL); 128 129 /* cleanup heap allocation */ 130 for (j=0; j<imgH; j++) 131 { 132 free(row_pointers[j]); 133 } 134 free(row_pointers); 135 136 fclose(fp); 137 return 0; 138 } 139 140 void main() 141 { 142 Mat img=imread("lena.jpg", 0); 143 namedWindow("lena"); 144 imshow("lena",img); 145 waitKey(0); 146 char imgName[10]="lena.png"; 147 int imgWidth=img.cols; 148 int imgHeight=img.rows; 149 int channels=img.channels(); 150 write_png_file(imgName , img, imgWidth, imgHeight, channels); 151 152 getchar(); 153 }