使用libjpeg库读取JPEG图像数据

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>就行了。
大部分照搬,细节可以看里面的英语注释,主要的几个地方修改下就行了,看下面的汉语注释:

// 这些和错误处理有关,不用管
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 %s\n", 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;
}
  • 6
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值