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 }