VC6 下 libpng 庫的編譯與初步使用
目錄
一、libpng 庫的介紹
libpng 用於處理 png 格式的圖片, 是一套比較完善的 png 圖片處理庫, 免費、開源, 因此受到了很高的好評。遺憾的是, 它的官方網站: htp://www.libpng.org/ 現已不能直接訪問。但是我們依然能夠通過 sourceforge 來下載所需的相關文件。
libpng 在 sourceforge 上的項目地址: http://sourceforge.net/projects/libpng/
目前最新版本的 libpng 為 1.61。
二、VC6 下 libpng 的編譯
1. 下載 libpng 與 zlib
筆者所用的IDE依然為 Visual Studio 6.0 ( VC++ 6 ), 所以這里以 VC6 下的編譯\使用來作介紹。
首先下載兩個庫, 一個是 libpng , 另一個則是 zlib 庫, zlib 庫是一套用於壓縮數據的庫, libpng 借助了該庫作為壓縮引擎, 也就是說, libpng 依賴於 zlib 庫。
關於這兩個庫的版本選擇, 最新版本的 libpng 和 zlib 都沒有提供適用於 VC6 的工程文件, 但是提供的有 vc 9\10 的, 當然, 新版本的 VS 可以將舊的工程文件來進行轉換, 但是反過來不行。 因此要下載到適合 VC6 進行編譯的版本。
筆者的選擇是:
- libpng 1.4.12 版本, 下載地址: http://sourceforge.net/projects/libpng/files/libpng14/1.4.12/lpng1412.zip/download
- zlib 1.2.3 版本, 下載地址: http://sourceforge.net/projects/libpng/files/zlib/1.2.3/zlib123.zip/download
如果使用的是更高版本的VS, 那么你也可以從該頁 http://sourceforge.net/projects/libpng/files/ 選擇適合你的 libpng 和 zlib。
2. 進行編譯
將下載到的文件( lpng1412.zip、zlib123.zip )進行解壓后(任意目錄, 例如: E:\\lpng1412), 進入到 libpng 的解壓目錄, 找到 libpng 的工作空間文件, 位於:
\\lpng1412\\projects\\visualc6\\libpng.dsw
將該工作區文件打開時, VC6會提示要找到 zlib 庫的工程文件, 如圖:
這時通過文件選擇對話框找到 zlib 工程文件 zlib.dsp 所在的位置后, 點OK進行確定。 zlib 工程文件位於 zlib 解壓文件夾中的:
\\zlib123\\projects\\visualc6\\zlib.dsp
此時工作區中有三個項目, libpng、pngtest、zlib, 在組建工具欄中, 如圖:
選擇需要的編譯方式, 如果你的 VC6 常用工具欄中沒有如圖所示的選項, 右鍵工具欄的空白處, 在彈出的菜單中選擇 "Build" 將該工具欄調出, VC6安裝時默認只有一個 "Build MiniBar"。
一般情況下, 我們需要以 .lib 方式進行調用, 所以這里使用 Win32 LIB Debug 和 Win32 LIB Release 兩種模式對 libpng 各進行一次編譯, 也就得到了兩個 lib 版本, 一個份 debug 的, 一份是 release 的。
如果需要以 dll 方式進行調用( Win32 DLL Debug\Release ), 或者打算給 VB 進行調用( Win32 DLL VB ), 那么也可以根據自己需要選擇其他的編譯方式。
3. 得到 .lib 文件
編譯完成后, 如果沒有出現錯誤, 此時在 libpng 和 zlib 庫的工程文件所在的文件夾下均會出現 Win32_LIB_Debug 和 Win32_LIB_Release 兩個文件夾, 檢查這4個文件夾中是否有以下4個文件:
- 1>. zlib 庫:
- zlibd.lib ( Win32_LIB_Debug 模式生成 )
- zlib.lib ( Win32_LIB_Release 模式生成 )
- 2>. libpng 庫:
- libpngd.lib ( Win32_LIB_Debug 模式生成 )
- libpng.lib ( Win32_LIB_Release 模式生成 )
如果存在, 恭喜, 編譯完成。
三、初步使用
1. 對 VC6 進行設置
庫雖然已經編譯完成了, 但是如果要使用, 我們還得將其加入到 VC6 的目錄中, 讓 VC6 在編譯鏈接時能夠找到這兩個庫。
菜單欄 -> 工具(Tools) -> 選項(Options) -> 目錄選項卡(Directories)
在 include files 選項中, 將 libpng 和 zlib 庫所在的文件夾加入其中(.h\.c源碼文件所在的文件夾)。
在 library files 選項中, 將剛剛編譯得到的 .lib 文件所在的文件夾加入其中。
完成后如上圖所示, 當然, 如果你嫌lib路徑中一次添加4個文件夾路徑有點浪費, 那么你完全可以將那 4 個 .lib 文件放在一個文件夾下再添加進去, 或者直接復制到已有的 lib 路徑文件夾下都行。
2. 將 .lib 文件添加到工程設置中
新建一個工程, 工程類型就選 Win32 Console Application 的空工程吧, 在工程設置(Projet Settings)中 ( 工作空間 -> 右鍵工程 -> 設置...(Settings...) 的 鏈接(Link) 選項卡中的 對象\庫模塊(Object\library modules) 中添加剛剛編譯得到的 .lib 文件名稱.
Win32 Debug 添加 zlibd.lib libpngd.lib , Win32 Release 模式添加 zlib.lib libpng.lib
如果你不想這樣做, 也可以使用 #pragma comment(lib, "libpng.lib") 這個的命令來完成。
3. 使用 libpng 檢測文件是否為 png 格式的圖像
假設上面的步驟都已經完成后, 我們來寫一段代碼測試下 libpng 是否已經可用, 這段代碼的作用是檢查一個文件是否為 png 格式的圖片:
1 #include <stdio.h> 2 #include "png.h" // libpng 庫的一個重要頭文件 3 4 int main() 5 { 6 int is_png; //是否為png 7 char cbHeader[8]; //文件頭 8 FILE *fp = fopen( "test.png", "rb" ); 9 10 if( !fp ) 11 { 12 puts( "文件打開錯誤!" ); 13 return 0; 14 } 15 16 fread( cbHeader, 1, 8, fp ); //從文件中讀取文件頭 17 18 is_png = png_sig_cmp( cbHeader, 0, 8 ); //檢測該文件頭是否為 png 格式的圖片 19 20 is_png == 0 ? puts( "是png" ) : puts( "不是png" ); 21 22 return 0; 23 }
編譯運行, 會發現出現了幾下如下的錯誤:
Compiling... main.c Linking... MSVCRT.lib(MSVCRT.dll) : error LNK2005: __snprintf already defined in LIBCD.lib(snprintf.obj) MSVCRT.lib(MSVCRT.dll) : error LNK2005: _malloc already defined in LIBCD.lib(dbgheap.obj) MSVCRT.lib(MSVCRT.dll) : error LNK2005: _free already defined in LIBCD.lib(dbgheap.obj) LINK : warning LNK4098: defaultlib "MSVCRT" conflicts with use of other libs; use /NODEFAULTLIB:library Debug/libpng_demo.exe : fatal error LNK1169: one or more multiply defined symbols found Error executing link.exe. libpng_demo.exe - 4 error(s), 1 warning(s)
大致的意思是說 xxx 在 LIBCD.lib 中已經有了定義, 這個比較好解決, 我們選擇將 LIBCD.lib 這個庫進行忽略即可, 忽略的方式為, 進入工程設置, 找到 Link 選項卡, 在分類(Categor)中選擇 輸入(Input), 下面有個 忽略庫(Ignore libraries), 將 LIBCD.lib 添加進去確定。如果選擇Win32 Release 模式, 也會出現這個錯誤, 不過重復定義的庫變成了 LIBC.lib, 同樣方式進行忽略即可。
再次編譯運行, 錯誤即消失, 0 error(s), 0 warning(s), 十分愜意。
代碼解說:
在上段代碼中, 我們運用了 libpng 提供的一個 png_sig_cmp 函數, 該函數的作用是通過文件頭檢測文件是否為png格式的圖片, 對於 png 格式的圖片, 文件開頭的 8 字節來表示該文件是不是PNG文件(詳見png的文件結構), 當 是png時, 函數返回 0。
因此, 在代碼中我們定義了 8 個字節的存儲空間 char cbHeader[8]; 並且使用標准輸入輸出函數讀取了文件的前8個字節的內容, 將得到的文件頭再交給 png_sig_cmp 進行判斷。
筆者也是剛接觸這個 libpng 庫, 對於詳細的使用方法還有待研究, 由於官網... 就不說了, 相關的完整資料也不太好找, 不過還是通過.找到了一份完整的文檔(pdf, 英文)。
下載地址: http://files.cnblogs.com/mr-wid/libpng-1.4.0-manual.zip
--------------------
wid, 2013.04.19