一、解压 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;
1
2
2. struct jpeg_error_mgr 结构体:
该结构体定义的变量,用于处理 libjpeg 库解码 jpeg 数据时的错误处理。
/* 用于错误处理的结构体对象 */
struct jpeg_error_mgr jerr;
1
2
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); 1
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); 1 2
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);
1
2
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);
1
2
3
11.释放解码对象:
jpeg_destroy_decompress(&cinfo); fclose(infile); //关闭 jpg 图像文件
1
2
总结
libjpeg解码 jpeg文件 主要就是依靠上面几步。大家可以自己试试。
效果展示:
实验效果录制在 B站 :(有兴趣的可以看看实验效果)
https://www.bilibili.com/video/BV1zG4y1A7bT/?vd_source=986c364d205fa1124b337bc665f57c4f