在进行图片压缩编程之前必须先移植第三方库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);
}