当前位置: 首页 > 工具软件 > LibJPEG > 使用案例 >

libjpeg解码 jpeg文件

甘西岭
2023-12-01

Libjpeg 是一个广泛使用的 C 库,用于读取和写入 JPEG 图像文件。
这篇文章主要讲解在 LCD 上,使用 Libjpeg 库显示图片,以及图片的缩放。


一、解压 libjpeg-turbo-1.2.1.tar.gz 库

libjpeg-turbo-1.2.1.tar.gz库是以 .tar.gz 结尾的文件。

解压到当前文件:
tar -zxvf 压缩文件名.tar.gz

二、Libjpeg 的使用介绍

1. struct jpeg_decompress_struct 结构体:

用于定义一个结构体变量 cinfo 。该变量保存着 jpeg 数据的详细信息也保存着输出数据的详细信息。

/* 解压缩对象 */
struct jpeg_decompress_struct cinfo; 

2. struct jpeg_error_mgr 结构体:

该结构体定义的变量,用于处理 libjpeg 库解码 jpeg 数据时的错误处理。

/* 用于错误处理的结构体对象 */
struct jpeg_error_mgr jerr;

3.设置错误处理函数:

libjpeg 库解码 jpeg 数据时,可能出现内存不足导致错误,可以 调用默认错误处理函数继而会调用exit 函数结束整个进程

当然,我们也可以使用 libjpeg 提供的接口注册自定义错误处理函数


	/* 将错误处理结构对象绑定在JPEG对象上 */
    cinfo.err = jpeg_std_error(&jerr);
    
	//设置自定义错误处理函数 
	jerr.error_exit = my_error_exit;
	void my_error_exit(struct jpeg_decompress_struct *cinfo)
	{
	    /* ... */
	}
	

4.初始化解码对象(cinfo结构):

jpeg_create_decompress(&cinfo);

5.指定解压源文件:

	FILE * infile;
	
	/* 打开jpg 图像文件,argv[1] 是jpeg图片名 */
	if ((infile = fopen(argv[1], "rb")) == NULL) 
	 {
		return -1;
	}
	
	/* 指定源文件 */
	jpeg_stdio_src(&cinfo, infile);

6. 获取文件信息:

	/* 获得jpg信息 */
	jpeg_read_header(&cinfo, TRUE);

7.设置解压参数:

在开始解压缩之前可以进行解压缩参数的设定,也就是为cinfo结构的成员赋值。我们需要使用 cinfo.scale_num cinfo.scale_denom 这两个参数,来确定缩小比例。
可以设置 解压出来的图像的大小 与 原图 的比例,

例如:
cinfo. scale_num = 1;
cinfo. scale_denom = 2;
则解压出来的图片是原图的 1/2.

PEG 当前仅支持 1/1、 1/2、 1/4、 和 1/8 这几种缩小比例。 默认是 1/1,就是保持原图大小

8.开始解压:

jpeg_start_decompress(&cinfo);

9.读取数据:

解码后的数据是 按行 取出的。数据像素按照scanline来存储,scanline 是从左到右,从上到下的顺序,每个像素对应的各颜色或灰度通道数据是依次存储。一个 scanline 中的数据存储模式是R,G,B,R,G,B,R,G,B**,…。

因为是 按行 读取数据,所以要 计算 每行数据 的空间大小。我们定义一个缓冲区发 buffer 来存放数据。

(1) 计算 每行数据 的空间大小:

cinfo. output_components 为每个像素字节大小
cinfo. output_width 输出图像的宽度。
.

	unsigned char *buffer;
	int row_stride;
	
	// 一行的数据的空间大小
	row_stride = cinfo.output_width * cinfo.output_components;
	buffer = malloc(row_stride);

(2) 调用 jpeg_read_scanlines()来读取数据
jpeg_read_scanlines()可以指定一次读多少行,但是目前该函数还只能支持一次只读 1 行.

	// 循环调用jpeg_read_scanlines来一行一行地获得解压的数据
	while (cinfo.output_scanline < cinfo.output_height) 
	{
		(void) jpeg_read_scanlines(&cinfo, &buffer, 1);
	}

10.解压缩完毕

free(buffer); //释放 malloc 申请的空间
jpeg_finish_decompress(&cinfo);

11.释放解码对象:

jpeg_destroy_decompress(&cinfo);
fclose(infile); //关闭 jpg 图像文件

总结

libjpeg解码 jpeg文件 主要就是依靠上面几步。大家可以自己试试。

效果展示:

实验效果录制在 B站 :(有兴趣的可以看看实验效果)
https://www.bilibili.com/video/BV1zG4y1A7bT/?vd_source=986c364d205fa1124b337bc665f57c4f

 类似资料: