一、下載
libpng:http://libmng.com/pub/png/libpng.html
zlib:http://www.zlib.net/
IDE:VS2010
二、編譯
將下載的兩個zip解壓到同一目錄下
打開ibpng目錄下的projects\vstudio中的工程文件(低版本的VS可以打開projects\visualc71中的工程)。
編譯運行,在輸出目錄(Debug或Realse)中得到輸出文件libpng16.dll、libpng16.lib、zlib.lib。
三、創建工程
創建一個工程,右鍵點擊工程名打開Properties(屬性)對話框
在C/C++->General(常規)->Additional Include Directories(附加包含目錄)中添加libpng目錄
在Linker->General(常規)->Additional Library Directories(附加庫目錄)中添加剛剛生成的lib文件所在的路徑
在Linker->Input(輸入)->Additional Dependencies(附加依賴項)中添加libpng16.lib、zlib.lib兩個文件
四、運行
這里有一個簡單的例子,原文:http://zarb.org/~gc/html/libpng.html

/* * Copyright 2002-2010 Guillaume Cottenceau. * * This software may be freely redistributed under the terms * of the X11 license. * */ #include <unistd.h> #include <stdlib.h> #include <stdio.h> #include <string.h> #include <stdarg.h> #define PNG_DEBUG 3 #include <png.h> void abort_(const char * s, ...) { va_list args; va_start(args, s); vfprintf(stderr, s, args); fprintf(stderr, "\n"); va_end(args); abort(); } int x, y; int width, height; png_byte color_type; png_byte bit_depth; png_structp png_ptr; png_infop info_ptr; int number_of_passes; png_bytep * row_pointers; void read_png_file(char* file_name) { char header[8]; // 8 is the maximum size that can be checked /* open file and test for it being a png */ FILE *fp = fopen(file_name, "rb"); if (!fp) abort_("[read_png_file] File %s could not be opened for reading", file_name); fread(header, 1, 8, fp); if (png_sig_cmp(header, 0, 8)) abort_("[read_png_file] File %s is not recognized as a PNG file", file_name); /* initialize stuff */ png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (!png_ptr) abort_("[read_png_file] png_create_read_struct failed"); info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) abort_("[read_png_file] png_create_info_struct failed"); if (setjmp(png_jmpbuf(png_ptr))) abort_("[read_png_file] Error during init_io"); png_init_io(png_ptr, fp); png_set_sig_bytes(png_ptr, 8); png_read_info(png_ptr, info_ptr); width = png_get_image_width(png_ptr, info_ptr); height = png_get_image_height(png_ptr, info_ptr); color_type = png_get_color_type(png_ptr, info_ptr); bit_depth = png_get_bit_depth(png_ptr, info_ptr); number_of_passes = png_set_interlace_handling(png_ptr); png_read_update_info(png_ptr, info_ptr); /* read file */ if (setjmp(png_jmpbuf(png_ptr))) abort_("[read_png_file] Error during read_image"); row_pointers = (png_bytep*) malloc(sizeof(png_bytep) * height); for (y=0; y<height; y++) row_pointers[y] = (png_byte*) malloc(png_get_rowbytes(png_ptr,info_ptr)); png_read_image(png_ptr, row_pointers); fclose(fp); } void write_png_file(char* file_name) { /* create file */ FILE *fp = fopen(file_name, "wb"); if (!fp) abort_("[write_png_file] File %s could not be opened for writing", file_name); /* initialize stuff */ png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (!png_ptr) abort_("[write_png_file] png_create_write_struct failed"); info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) abort_("[write_png_file] png_create_info_struct failed"); if (setjmp(png_jmpbuf(png_ptr))) abort_("[write_png_file] Error during init_io"); png_init_io(png_ptr, fp); /* write header */ if (setjmp(png_jmpbuf(png_ptr))) abort_("[write_png_file] Error during writing header"); png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth, color_type, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); png_write_info(png_ptr, info_ptr); /* write bytes */ if (setjmp(png_jmpbuf(png_ptr))) abort_("[write_png_file] Error during writing bytes"); png_write_image(png_ptr, row_pointers); /* end write */ if (setjmp(png_jmpbuf(png_ptr))) abort_("[write_png_file] Error during end of write"); png_write_end(png_ptr, NULL); /* cleanup heap allocation */ for (y=0; y<height; y++) free(row_pointers[y]); free(row_pointers); fclose(fp); } void process_file(void) { if (png_get_color_type(png_ptr, info_ptr) == PNG_COLOR_TYPE_RGB) abort_("[process_file] input file is PNG_COLOR_TYPE_RGB but must be PNG_COLOR_TYPE_RGBA " "(lacks the alpha channel)"); if (png_get_color_type(png_ptr, info_ptr) != PNG_COLOR_TYPE_RGBA) abort_("[process_file] color_type of input file must be PNG_COLOR_TYPE_RGBA (%d) (is %d)", PNG_COLOR_TYPE_RGBA, png_get_color_type(png_ptr, info_ptr)); for (y=0; y<height; y++) { png_byte* row = row_pointers[y]; for (x=0; x<width; x++) { png_byte* ptr = &(row[x*4]); printf("Pixel at position [ %d - %d ] has RGBA values: %d - %d - %d - %d\n", x, y, ptr[0], ptr[1], ptr[2], ptr[3]); /* set red value to 0 and green value to the blue one */ ptr[0] = 0; ptr[1] = ptr[2]; } } } int main(int argc, char **argv) { if (argc != 3) abort_("Usage: program_name <file_in> <file_out>"); read_png_file(argv[1]); process_file(); write_png_file(argv[2]); return 0; }
若編譯錯誤,需要注意:C語言中,變量需要在函數或語句塊的開始聲明和定義。
若運行時提示缺少libpng16.dll,則將剛剛生成的libpng16.dll文件復制到工程目錄(Debug或Realse)中即可。也可以復制到系統目錄Windows\System32(64位操作系統需復制到Windows\SysWOW64)中。
若在執行png_read_info(png_ptr, info_ptr)時,出現錯誤"Unhandled exception at 0x7c928fea in myApp.exe: 0xC0000005: Access violation writing location 0x00000010.",則引用一段話
I solved my problem...
I found someone on LibPNG's mailing who had the same problem.
The solution is relatively simple: just be sure that the project in which you are using LibPng is compiled with the same "Runtime Library" settings. I think that by default the lib is compiled in "/MD" (multi-threaded DLL) and a lot of projects are single threaded by default. This setting can be found in the project's property under C++/Code Generation (in VC7.1).
So, just insure that the setting are the same for both the library and your project and you should be all set.
This is something that really ought to be mentionned in the documents somewhere (I know that GnuWin32 does not make any documents, but maybe a quick readme with the installer?).
Anyway, thanks!
--Yop83
也就是說,在編譯libpng和調用它執行程序時,必須用相同的"Runtime Library"設置。
這里我也碰到了這個問題,是因為編譯的時候用的VS2010,創建工程用的VS2008。后來改用為VS2010創建工程,沒有問題。