Libjpeg 是一个广泛使用的 C 库,用于读取和写入 JPEG 图像文件。
这篇文章主要讲解在 LCD 上,使用 Libjpeg 库显示图片,以及图片的缩放。
libjpeg-turbo-1.2.1.tar.gz
库是以 .tar.gz 结尾的文件。
解压到当前文件:
tar -zxvf 压缩文件名.tar.gz
用于定义一个结构体变量 cinfo
。该变量保存着 jpeg 数据的详细信息,也保存着输出数据的详细信息。
/* 解压缩对象 */
struct jpeg_decompress_struct cinfo;
该结构体定义的变量,用于处理 libjpeg 库解码 jpeg 数据时的错误处理。
/* 用于错误处理的结构体对象 */
struct jpeg_error_mgr jerr;
用 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)
{
/* ... */
}
jpeg_create_decompress(&cinfo);
FILE * infile;
/* 打开jpg 图像文件,argv[1] 是jpeg图片名 */
if ((infile = fopen(argv[1], "rb")) == NULL)
{
return -1;
}
/* 指定源文件 */
jpeg_stdio_src(&cinfo, infile);
/* 获得jpg信息 */
jpeg_read_header(&cinfo, TRUE);
在开始解压缩之前可以进行解压缩参数的设定,也就是为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,就是保持原图大小。
jpeg_start_decompress(&cinfo);
解码后的数据是 按行 取出的。数据像素按照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);
}
free(buffer); //释放 malloc 申请的空间
jpeg_finish_decompress(&cinfo);
jpeg_destroy_decompress(&cinfo);
fclose(infile); //关闭 jpg 图像文件
libjpeg解码 jpeg文件 主要就是依靠上面几步。大家可以自己试试。
实验效果录制在 B站 :(有兴趣的可以看看实验效果)
https://www.bilibili.com/video/BV1zG4y1A7bT/?vd_source=986c364d205fa1124b337bc665f57c4f