您的位置:首页 > 其它

使用libjpeg对图像进行压缩

2013-04-12 12:34 169 查看
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来释放内存。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: