LIBJPEG 安裝編譯,讀取jpeg影象資料
阿新 • • 發佈:2020-09-15
jpeg是一個國際影象壓縮標準,影象的字尾一般為jpeg
或者jpg
。這種圖片格式非常常見,還是有必要知道怎樣將資料讀取出來的。
在我做的zMatrix
庫裡,之前一直使用openCV
的函式imread()
讀取影象,不是很方便,查過很多資料後發現,如果自己從零寫一個讀取jpeg
的程式非常麻煩(可能水平不夠吧,可以查一下都是需要什麼演算法),需要用到一些比較複雜的壓縮演算法,又因為讀取影象不是重點,所以可以使用開源的庫達到同樣的目的,以後有空了可以自己實現。
使用的庫是libjpeg
,官網連結:http://libjpeg.sourceforge.net/,下載連結:http://www.ijg.org/files/ ,我使用的是9b這個版本。
接下來說一下在windows
平臺怎樣使用這個庫。
一、 編譯
1、下載並解壓,放在一個好找的目錄就行:
2、進入jpeg-9b,找到jconfig.cv,複製並改名為jconfig.h,否則會產生無法生成jconfig的警告
3、找到makefile.vc這個檔案,開啟(隨便一個文字編輯器)找到這一行
把路徑改為win32.mk
在你電腦上的路徑,每個人的可能不太一樣,路徑差別可能不是很大,我的是C:\Program Files (x86)\Microsoft SDKs\Windows\v7.1A\Include\win32.mak
,改為
4、準備編譯,我用的是VS2015命令提示符,不要選ARM的
5、進入jpeg-9b的目錄,輸入編譯命令開始編譯
命令:nmake -f makefile.vc
6、編譯後在目錄下找到庫libjpeg.lib
就編譯成功了。
二、使用
具體的使用在目錄下的example.c中有,註釋非常細,看了基本就會用了。這裡我簡單說說用法。
1、使用配置
有兩種方法:
第一種:新增libjpeg的標頭檔案的路徑和lib的路徑到VS的工程中,專案屬性頁
,然後在
中新增libjpeg.lib
第二種:把用到的標頭檔案和libjpeg.lib拷到你的工程中,只在工程裡做第一種的第三步新增libjpeg.lib就行了。
2、使用
程式裡包含標頭檔案#include <jpeglib.h>
就行了。
大部分照搬,細節可以看裡面的英語註釋,主要的幾個地方修改下就行了,看下面的漢語註釋:
1 // 這些和錯誤處理有關,不用管
2 struct my_error_mgr {
3 struct jpeg_error_mgr pub; /* "public" fields */
4
5 jmp_buf setjmp_buffer; /* for return to caller */
6 };
7
8 typedef struct my_error_mgr * my_error_ptr;
9
10 METHODDEF(void) my_error_exit(j_common_ptr cinfo)
11 {
12 my_error_ptr myerr = (my_error_ptr)cinfo->err;
13 (*cinfo->err->output_message) (cinfo);
14 longjmp(myerr->setjmp_buffer, 1);
15 }
16
17 // 讀取影象的函式
18 // 我添加了一個引數,是我庫裡的zMatrix類物件,用於儲存讀取的圖片資料
19 GLOBAL(int) read_JPEG_file(char * filename, z::Matrix8u & img)
20 {
21 struct jpeg_decompress_struct cinfo;
22 struct my_error_mgr jerr;
23 FILE * infile;
24 JSAMPARRAY buffer;
25 int row_stride;
26
27 if ((infile = fopen(filename, "rb")) == NULL) {
28 fprintf(stderr, "can't open %s\n", filename);
29 return 0;
30 }
31 cinfo.err = jpeg_std_error(&jerr.pub);
32 jerr.pub.error_exit = my_error_exit;
33 if (setjmp(jerr.setjmp_buffer)) {
34 jpeg_destroy_decompress(&cinfo);
35 fclose(infile);
36 return 0;
37 }
38 jpeg_create_decompress(&cinfo);
39
40 jpeg_stdio_src(&cinfo, infile);
41
42 // 這個函式獲取了讀取圖片的資訊,包括圖片的高和寬
43 (void)jpeg_read_header(&cinfo, TRUE);
44 // 在這裡新增你自己的程式碼,獲取或使用者到影象資訊
45 img.create(cinfo.image_height, cinfo.image_width, 3);
46
47 (void)jpeg_start_decompress(&cinfo);
48
49 row_stride = cinfo.output_width * cinfo.output_components;
50 buffer = (*cinfo.mem->alloc_sarray)((j_common_ptr)&cinfo, JPOOL_IMAGE, row_stride, 1);
51
52 while (cinfo.output_scanline < cinfo.output_height) {
53 // 一行一行的讀取
54 (void)jpeg_read_scanlines(&cinfo, buffer, 1);
55
56 // 在這裡新增程式碼獲取到圖片的畫素資料
57 // buffer儲存了讀取的當前行的資料,儲存順序是RGB
58 // output_scanline是已經讀取過的行數
59 for (int i = 0; i < img.cols; ++i) {
60 img[cinfo.output_scanline - 1][i * 3 + 2] = buffer[0][i * 3 + 0];
61 img[cinfo.output_scanline - 1][i * 3 + 1] = buffer[0][i * 3 + 1];
62 img[cinfo.output_scanline - 1][i * 3 + 0] = buffer[0][i * 3 + 2];
63 }
64 }
65
66 (void)jpeg_finish_decompress(&cinfo);
67 jpeg_destroy_decompress(&cinfo);
68 fclose(infile);
69 return 1;
70 }