使用libjpeg对图像进行压缩

您所在的位置:网站首页 jpg压缩文件怎么压缩 使用libjpeg对图像进行压缩

使用libjpeg对图像进行压缩

2024-06-21 19:32| 来源: 网络整理| 查看: 265

  libjpeg 是一个完全用C语言编写的库,包含了被广泛使用的JPEG解码、JPEG编码和其他的JPEG功能的实现。Libjpeg不仅可以把bmp格式转化成jpg格式,还支持其他格式的转化成jpg格式(例如ppm,gif,targa,rle等)。

转化流程如下:

(1) 分配和初始化一个JPEG压缩对象

在libjpeg中,JPEG压缩对象被定义为“struct  jpeg_compress_struct”(这个结构体内部有一些子结构体,这些子结构体时通过“malloc”来分配空间的,我们的程序不会直接使用这些结构体)。

我们还需要定于错误处理器。这里我们仅使用默认的错误处理器,默认的错误处理器会把警告/错误信息输出到stderr,如果出现致命错误,将会调用exit()退出程序。

绑定错误处理器的代码如下:

struct jpeg_compress_struct cinfo; struct jpeg_error_mgr jerr; ... cinfo.err = jpeg_std_error(&jerr); jpeg_create_compress(&cinfo);

jpeg_create_compress会分配一小段内存,如果我们机器内存过少则会分配失败。在这种情况下error handler会处理错误并退出程序。这就是为什么error handler为什么需要首先进行初始化的原因。

 

(2) 指定压缩数据保存的位置

Libjpeg库把压缩后的数据传输到“数据目的”模块。在本库中包含把数据写入到标准流的“数据目的”模块。如果想把数据写入到其他地方(比如内存),可以自定义“数据目的”模块。以下是示例代码:

 

FILE * outfile; ... if ((outfile = fopen(filename, "wb")) == NULL) { writeLog(…); } jpeg_stdio_dest(&cinfo, outfile);

最后一个函数调用了标准“数据目的”模块。

可以选择在设置参数(步骤3)后再数据目的,但不能在jpeg_start_compress()和jpeg_finish_compress()之间更改数据目的。

(3) 设置压缩对象的参数

我们必须在JPEG压缩对象中设置源图片的以下信息:

       image_width             图片的宽度,以像素为单位

       image_height             图片的高度,以像素为单位

      input_components     色彩通道数(每像素采样)

       in_color_space    源文件的色彩空间

      input_components为1代表灰度图,在等于3时代表彩色位图图像

      in_color_space为JCS_GRAYSCALE表示灰度图,在等于JCS_RGB时代表彩色位图图像

        JPEG需要提供大量的参数来决定我们如何对参数进行编码。大多数情况下我们不需要知道所有的参数,我们可以使用jpeg_set_defaults()把参数设置成合理的默认值。然后,再设置我们需要更改的参数。

        jpeg_set_defaults()依赖于源图像的色彩空间,我们需要在调用jpeg_set_defaults()之前正确设置in_color_space。以下是设置压缩对象的参数的参考代码:

cinfo.image_width = Width; cinfo.image_height = Height; cinfo.input_components = 3; cinfo.in_color_space = JCS_RGB; jpeg_set_defaults(&cinfo); //设置压缩参  数

(4)jpeg_start_compress(...)

在设置完数据目的和源图像的所有信息和参数后,我们就可以通过调用jpeg_start_compress()来启动一个压缩循环。jpeg_start_compress()会初始化内部的状态,分配工作空间。并且产生JPEG文件头的数据流。示例代码:

       jpeg_start_compress(&cinfo, TRUE);

在这里”TRUE”代表我们需要写入一个完整的数据流

(5) 逐行压缩图像

现在我们可以通过调用jpeg_write_scanlines()写入图象数据了。图象数据应该按照自底向上的顺序进行扫描。

(6jpeg_finish_compress

当所有的图像数据都被写入后,我们调用jpeg_finish_compress来结束压缩循环。这是为了确保所有的数据都被写入数据目的。jpeg_finish_compress同时也承担着释放JPEG对象开辟的内存的工作。一般代码如下:

jpeg_finish_compress(&cinfo);

(7 释放JPEG压缩对象

当对一个JPEG对象完成压缩后,调用jpeg_destroy_compress来释放内存。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3