使用libjpeg库将bmp图片压缩成jpg

在进行图片压缩编程之前必须先移植第三方库libjpeg.so。

我用的是jpegsrc.v8c.tar.gz版本,具体的安装过程如下:

1、解压:#tar -xzvf jpegsrc.v8d.tar.gz

2、进入解压后的目录:#cd jpeg-8c

3、创建文件夹,用于存放生成的库文件和相关头文件:#mkdir /root/jpeg_8

4、配置编译工具和生成目标文件该存放的文件夹:#./configure --prefix=/root/jpeg_8 --host=arm-cortex_a8-linux-gnueabi

“/root/jpeg_8”这个文件夹根据自己需要设置,编译工具也要根据需要设置:arm-cortex_a8-linux-gnueabi


libjpeg库生成了就可以开始图片压缩的编程了,如下:

1、图片的压缩需要一个jpeg对象,jpeg对象是一个jpeg_decompress_struct结构体,同时还需要一个错误处理结构体对象,该对象是jpeg_error_mgr。

struct jpeg_compress_struct toWriteCinfo;  //定义jpeg对象
struct jpeg_error_mgr jerr; //定义错误处理对象

2、将错误处理对象绑定在jpeg对象上

toWriteCinfo.err = jpeg_std_error(&jerr); 

3、初始化jpeg对象

jpeg_create_compress(&toWriteCinfo);  

4、确定要用于输出压缩后的jpeg的数据空间,这里用unsigned char **jpeg_buf类型的指针,unsigned long int *jpeg_len指针指向的空间用于存储jpeg图片的大小   

jpeg_mem_dest(&toWriteCinfo, jpeg_buf, jpeg_len);

5、设置压缩参数,主要参数有图像宽、高、色彩通道数(1:索引图像 3:其他),色彩空间(JCS_GRAYSCALE表示灰度图,JCS_RGB表示彩色图像),压缩质量等

toWriteCinfo.image_width = ctrl_tmp.width;   //jpeg图像宽
toWriteCinfo.image_height = ctrl_tmp.height;  //jpeg图像高
toWriteCinfo.input_components = 3;   //jpeg图像色彩通道数
toWriteCinfo.in_color_space = JCS_RGB;   //jpeg图像色彩空间


6、调用jpeg_set_defaults函数,jpeglib库将采用默认的设置对图像进行压缩,如果需要改变设置,如压缩质量,调用这个函数后,可以调用其它设置函数,如jpeg_set_quality函数。

jpeg_set_defaults(&toWriteCinfo);  
jpeg_set_quality(&toWriteCinfo, 90, 1);

7、开始压缩

jpeg_start_compress(&toWriteCinfo,1); 

8、接收jpeg图片的数据

JSAMPROW row_pointer[1];     //JSAMPROW一般是unsigned char *类型

row_stride = toWriteCinfo.image_width * 3; //一行像素点的字节数,如果是索引图,就不需要乘以3了

while(toWriteCinfo.next_scanline < ctrl_tmp.height)  
{  
row_pointer[0] = & bmp_data[toWriteCinfo.next_scanline * row_stride];  //bmp_data是我malloc的一段内存用于存储bmp数据,下面再具体描述
(void)jpeg_write_scanlines(&toWriteCinfo, row_pointer, 1);   //将一行数据写到jpeg_buf里

9、最后就是释放压缩工作过程中所申请的资源了

jpeg_finish_compress(&toWriteCinfo);  
jpeg_destroy_compress(&toWriteCinfo);

大致的压缩流程到这里,大致已经写完,还有一点要注意的是被压缩的bmp图像的数据要读入bmp_data里,而且这段bmp数据不包括bmp的头,一般的bmp头是54(彩色图)。


就到这里吧,有不清楚的同学可以留言给我。

下面是我写的代码:

jpeg_buf:用于接收jpeg图片的数据,jpeg_len:jpeg图片的大小,bmp_data:传入bmp数据

/*----------------------将图片bmp压缩成jpg------------------------------*/
void get_jpeg(unsigned char **jpeg_buf, unsigned long int *jpeg_len, char *bmp_data)  
{  
// int jpegWidth = ctrl_tmp.width;  
// int jpegHeight = ctrl_tmp.height; 


struct jpeg_compress_struct toWriteCinfo;  
struct jpeg_error_mgr jerr;  
JSAMPROW row_pointer[1];  
int row_stride;  

//开始进行jpg的数据写入   
toWriteCinfo.err = jpeg_std_error(&jerr);  
jpeg_create_compress(&toWriteCinfo);  
//确定要用于输出压缩的jpeg的数据空间   
jpeg_mem_dest(&toWriteCinfo, jpeg_buf, jpeg_len);  
  
toWriteCinfo.image_width = ctrl_tmp.width;  
toWriteCinfo.image_height = ctrl_tmp.height;  
toWriteCinfo.input_components = 3;  
toWriteCinfo.in_color_space = JCS_RGB;  
  
jpeg_set_defaults(&toWriteCinfo);  
jpeg_set_quality(&toWriteCinfo, 90, 1);  
jpeg_start_compress(&toWriteCinfo,1);  
row_stride = toWriteCinfo.image_width * 3;  
while(toWriteCinfo.next_scanline < ctrl_tmp.height)  
{  
row_pointer[0] = & bmp_data[toWriteCinfo.next_scanline * row_stride];  
(void)jpeg_write_scanlines(&toWriteCinfo, row_pointer, 1);  
}  
jpeg_finish_compress(&toWriteCinfo);  
jpeg_destroy_compress(&toWriteCinfo); 

你可能感兴趣的:(使用libjpeg库将bmp图片压缩成jpg)