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 }