jpeglib库实现MJPEG图像的压缩与解压缩
来源:互联网 发布:文明6好玩吗 知乎 编辑:程序博客网 时间:2024/05/18 18:17
linux提供了jpeglib库用于MJPEG图像的压缩与解压缩等,编写V4L2应用程序,编译的时候加上选项-ljpeg表示使用jpeg库中的API函数
关于jpeg库API使用的说明在网站:http://refspecs.linuxfoundation.org/LSB_3.1.0/LSB-Desktop-generic/LSB-Desktop-generic/toclibjpeg.html
一、压缩步骤
1、申请并初始化jpeg压缩对象,同时要指定错误处理器
struct jpeg_compress_struct cinfo;
// 声明错误处理器,并赋值给cinfo.err域
struct jpeg_error_mgr jem;
cinfo.err = jpeg_std_error(&jem);
jpeg_create_compress(&cinfo);
2、指定压缩后的图像所存放的目标文件,注意,目标文件应以二进制模式打开
f=fopen("test.jpg","wb");
if (f==NULL)
{
printf("can't open file test.jpg\n");
exit(1);
}
jpeg_stdio_dest(&cinfo, f);
3、设置压缩参数,主要参数有图像宽、高、色彩通道数(1:索引图像,3:其他),色彩空间(JCS_GRAYSCALE表示灰度图,JCS_RGB表示彩色图像),压缩质量等,如下:
cinfo.image_width = nWidth; // 为图的宽和高,单位为像素
cinfo.image_height = nHeight;
cinfo.input_components = 1; // 在此为1,表示灰度图, 如果是彩色位图,则为3
cinfo.in_color_space = JCS_GRAYSCALE; //JCS_GRAYSCALE表示灰度图,JCS_RGB表示彩色图像
jpeg_set_defaults(&cinfo);
jpeg_set_quality (&cinfo, 80, true);
需要注意的是,jpeg_set_defaults函数一定要等设置好图像宽、高、色彩通道数计色彩空间四个参数后才能调用,因为这个函数要用到这四个值,调用jpeg_set_defaults函数后,jpeglib库采用默认的设置对图像进行压缩,如果需要改变设置,如压缩质量,调用这个函数后,可以调用其它设置函数,如jpeg_set_quality函数。其实图像压缩时有好多参数可以设置,但大部分我们都用不着设置,只需调用jpeg_set_defaults函数值为默认值即可。
4、上面的工作准备完成后,就可以压缩了,压缩过程非常简单,首先调用jpeg_start_compress,然后可以对每一行进行压缩,也可以对若干行进行压缩,甚至可以对整个的图像进行一次压缩,压缩完成后,记得要调用jpeg_finish_compress函数,如下:
jpeg_start_compress(&cinfo, TRUE);
JSAMPROW row_pointer[1]; // 一行位图
int row_stride; // 每一行的字节数
row_stride = cinfo.image_width; // 如果不是索引图,此处需要乘以3
// 对每一行进行压缩
while (cinfo.next_scanline <cinfo.image_height) {
row_pointer[0] = & pDataConv[cinfo.next_scanline * row_stride];
jpeg_write_scanlines(&cinfo, row_pointer, 1);
}
jpeg_finish_compress(&cinfo);
5、最后就是释放压缩工作过程中所申请的资源了,主要就是jpeg压缩对象,由于在本例中我是直接用的局部变量,所以只需调用jpeg_destroy_compress这个函数即可,如下:
jpeg_destroy_compress(&cinfo);
二、解压缩步骤
解压缩步骤与压缩步骤非常相似,只是解压缩对象为jpeg_decompress_struct类型,步骤如下:
1、声明并初始化解压缩对象,同时制定错误信息管理器
struct jpeg_decompress_struct cinfo;
struct jpeg_error_mgr jerr;
cinfo.err = jpeg_std_error(&jerr);
jpeg_create_decompress(&cinfo);
2、打开jpg图像文件,并指定为解压缩对象的源文件
FILE *f = fopen(strSourceFileName,"rb");
if (f==NULL)
{
printf("Open file error!/n");
return;
}
jpeg_stdio_src(&cinfo, f);
3、读取图像信息
jpeg_read_header(&cinfo, TRUE);
4、根据图像信息申请一个图像缓冲区
data = new BYTE cinfo.image_width*cinfo.image_height*cinfo.num_components];
5、开始解压缩
jpeg_start_decompress(&cinfo);
JSAMPROW row_pointer[1];
while (cinfo.output_scanline < cinfo.output_height)
{
row_pointer[0] = &data[(cinfo.output_height - cinfo.output_scanline-1)*cinfo.image_width*cinfo.num_components];
jpeg_read_scanlines(&cinfo,row_pointer , 1);
}
jpeg_finish_decompress(&cinfo);
6、释放资源
jpeg_destroy_decompress(&cinfo);
fclose(f);
好了,利用IJG JPEG Library进行图像压缩就介绍到这里,希望对大家有所帮助
以下是部分压缩与解压缩的代码,方便大家参考,需要说明的是我这里MJPEG使用RGB数据压缩,然后MJPEG解压出来也是RGB数据,完整的程序下载在:http://download.csdn.net/detail/luckywang1103/6707987
三、压缩代码
void write_JPEG_file(unsigned char *buf, int size, int quality) { struct jpeg_compress_struct cinfo; struct jpeg_error_mgr jerr; FILE *outFile; /* target file */ JSAMPROW row_pointer[1];/* pointer to JSAMPLE row[s] */ unsigned char *line_buffer, *yuyv;/* physical row width in image buffer */ int z;line_buffer = calloc(WIDTH * 3, 1);yuyv = buf;printf("compress start...\n");cinfo.err = jpeg_std_error(&jerr); jpeg_create_compress(&cinfo); //Initialization of JPEG compression objects. if ( (outFile= fopen("testx.jpg", "wb")) == NULL) //open file { fprintf(stderr, "can't open %s\n", "testx.jpg"); exit(1); } jpeg_stdio_dest(&cinfo, outFile); //Initialize state for output to stdio stream cinfo.image_width = WIDTH; /* image width and height, in pixels */ cinfo.image_height = HEIGHT; cinfo.input_components = 3; /* # of color components per pixel */ cinfo.in_color_space = JCS_RGB; /* colorspace of input image */ jpeg_set_defaults(&cinfo); //set compression parameters to default values jpeg_set_quality(&cinfo, 80, TRUE ); //construct JPEG quantization tables for indicated quality (between 0 and 100) jpeg_start_compress(&cinfo, TRUE); //initialize a compression cycle z = 0;while(cinfo.next_scanline < HEIGHT){int x;unsigned char *ptr = line_buffer;for(x = 0; x < WIDTH; x++) {int r, g, b;int y, u, v;if(!z)y = yuyv[0] << 8;elsey = yuyv[2] << 8;u = yuyv[1] - 128;v = yuyv[3] - 128;r =(y +(359 * v)) >> 8;g =(y -(88 * u) -(183 * v)) >> 8;b =(y +(454 * u)) >> 8;*(ptr++) =(r > 255) ? 255 :((r < 0) ? 0 : r);*(ptr++) =(g > 255) ? 255 :((g < 0) ? 0 : g);*(ptr++) =(b > 255) ? 255 :((b < 0) ? 0 : b);if(z++) {z = 0;yuyv += 4;}}row_pointer[0] = line_buffer;jpeg_write_scanlines(&cinfo, row_pointer, 1);//cinfo.next_scanline会自动增加}jpeg_finish_compress(&cinfo); jpeg_destroy_compress(&cinfo); fclose(outFile); }//end write_JPEG_file
四、解压缩代码
if ((infile = fopen(s, "rb")) == NULL){fprintf(stderr, "open %s failed\n", s);exit(-1);}cinfo.err = jpeg_std_error(&jerr);jpeg_create_decompress(&cinfo);//导入要解压的Jpeg文件infilejpeg_stdio_src(&cinfo, infile);//读取jpeg文件的文件头jpeg_read_header(&cinfo, TRUE);//开始解压Jpeg文件,解压后将分配给scanline缓冲区,jpeg_start_decompress(&cinfo);buffer = (unsigned char *) malloc(cinfo.output_width * cinfo.output_components);y = 0;while (cinfo.output_scanline < cinfo.output_height){jpeg_read_scanlines(&cinfo, &buffer, 1);if (fbdev.fb_bpp == 16){unsigned short color;for (x = 0; x < cinfo.output_width; x++){color = RGB888toRGB565(buffer[x * 3],buffer[x * 3 + 1], buffer[x * 3 + 2]);fb_pixel(fbdev.fb_mem, fbdev.fb_width, fbdev.fb_height, x, y, color);///}}else if (fbdev.fb_bpp == 24){memcpy((unsigned char *)fbdev.fb_mem + y * fbdev.fb_width * 3, buffer,cinfo.output_width * cinfo.output_components);}y++;//下一个scanline}//完成Jpeg解码,释放Jpeg文件jpeg_finish_decompress(&cinfo);jpeg_destroy_decompress(&cinfo);//释放帧缓冲区free(buffer);
- jpeglib库实现MJPEG图像的压缩与解压缩
- 压缩与解压缩的实现
- 利用jpeglib库进行图像压缩和解压缩
- 哈夫曼树实现文件的压缩与解压缩
- java实现压缩与解压缩!
- C#实现压缩与解压缩
- MJPEG解压缩
- 利用jpeglib压缩图像为jpg格式
- 利用jpeglib压缩图像为jpg格式
- 利用jpeglib压缩图像为jpg格式
- Java压缩,解压缩的实现
- 利用JAVA API函数实现数据的压缩与解压缩
- 利用JAVA API函数实现数据的压缩与解压缩
- C#实现.rar的动态压缩与解压缩
- 无符号整形压缩与解压缩的一种实现
- java原生的zip压缩与解压缩实现
- 数据的压缩存储与解压缩算法实现(C语言)
- 利用JAVA API函数实现数据的压缩与解压缩
- MySQL业务分析小记
- 验证码之父:路易斯·范·安
- coreseek-4.1-win32 安装
- 垃圾回收GC:.Net自动内存管理 上(一)内存分配
- poj 2718 Smallest Difference
- jpeglib库实现MJPEG图像的压缩与解压缩
- 机器学习算法与Python实践之(四)支持向量机(SVM)实现
- S5PV210 金手指接口核心板Sate210-F 配套开发板全部硬件功能测试通过
- 闲话iBatis
- 算法之排序-----排序第一篇 快速排序
- Win7下 安全、彻底删除Orcale数据库
- 演算法筆記
- spring mvc使用uploadify上传
- C#通过thrift连接hbase操作步骤