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 SDKsWindowsv7.1AIncludewin32.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
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71// 这些和错误处理有关,不用管 struct my_error_mgr { struct jpeg_error_mgr pub; /* "public" fields */ jmp_buf setjmp_buffer; /* for return to caller */ }; typedef struct my_error_mgr * my_error_ptr; METHODDEF(void) my_error_exit(j_common_ptr cinfo) { my_error_ptr myerr = (my_error_ptr)cinfo->err; (*cinfo->err->output_message) (cinfo); longjmp(myerr->setjmp_buffer, 1); } // 读取图像的函数 // 我添加了一个参数,是我库里的zMatrix类对象,用于保存读取的图片数据 GLOBAL(int) read_JPEG_file(char * filename, z::Matrix8u & img) { struct jpeg_decompress_struct cinfo; struct my_error_mgr jerr; FILE * infile; JSAMPARRAY buffer; int row_stride; if ((infile = fopen(filename, "rb")) == NULL) { fprintf(stderr, "can't open %sn", filename); return 0; } cinfo.err = jpeg_std_error(&jerr.pub); jerr.pub.error_exit = my_error_exit; if (setjmp(jerr.setjmp_buffer)) { jpeg_destroy_decompress(&cinfo); fclose(infile); return 0; } jpeg_create_decompress(&cinfo); jpeg_stdio_src(&cinfo, infile); // 这个函数获取了读取图片的信息,包括图片的高和宽 (void)jpeg_read_header(&cinfo, TRUE); // 在这里添加你自己的代码,获取或用户到图像信息 img.create(cinfo.image_height, cinfo.image_width, 3); (void)jpeg_start_decompress(&cinfo); row_stride = cinfo.output_width * cinfo.output_components; buffer = (*cinfo.mem->alloc_sarray)((j_common_ptr)&cinfo, JPOOL_IMAGE, row_stride, 1); while (cinfo.output_scanline < cinfo.output_height) { // 一行一行的读取 (void)jpeg_read_scanlines(&cinfo, buffer, 1); // 在这里添加代码获取到图片的像素数据 // buffer保存了读取的当前行的数据,保存顺序是RGB // output_scanline是已经读取过的行数 for (int i = 0; i < img.cols; ++i) { img[cinfo.output_scanline - 1][i * 3 + 2] = buffer[0][i * 3 + 0]; img[cinfo.output_scanline - 1][i * 3 + 1] = buffer[0][i * 3 + 1]; img[cinfo.output_scanline - 1][i * 3 + 0] = buffer[0][i * 3 + 2]; } } (void)jpeg_finish_decompress(&cinfo); jpeg_destroy_decompress(&cinfo); fclose(infile); return 1; }
最后
以上就是潇洒万宝路最近收集整理的关于使用libjpeg库读取JPEG图像数据的全部内容,更多相关使用libjpeg库读取JPEG图像数据内容请搜索靠谱客的其他文章。
发表评论 取消回复