libjpeg库其实已经可以满足我们日常处理日常简单图片之间的转换了。下面就来介绍一下jpeg库的解压和压缩过程。

首先来讲解压操作过程:

1、分配jpeg对象结构体空间,并初始化。

2、指定解压数据源。

3、获取解压文件信息。

4、为解压设定参数,包括图像大小和颜色空间。

5、开始解压缩。

6、取数据。

7、解压完毕。

8、释放资源和退出程序。

1、分配jpeg对象结构体空间、并初始化。

解压缩过程中使用的JPEG对象是一个jpeg_decompress_struct的结构体。同时还需要定义一个用于错误处理的结构体对象,IJG中标准的错误结构体是jpeg_error_mgr。

    struct jpeg_decompress_struct cinfo;struct jpeg_error_mgr jerr;

绑定jerr错误结构体至jpeg对象结构体。

    cinfo.err = jpeg_std_error(&jerr);

这个标准的错误处理结构将使程序在出现错误时调用exit()退出程序,如果不希望使用标准的错误处理方式,则可以通过自定义退出函数的方法自定义错误处理结构。

初始化cinfo结构体。

 jpeg_create_decompress(&cinfo);

2、指定解压数据源。

利用标准C库的文件指针打开相关jpg文件。

     FILE * infile;if ((infile = fopen("test.jpg", "rb")) == NULL){
perror("fopen fail");
return 0;}jpeg_stdio_src(&cinfo, infile);

3、获取解压文件信息。

将图像的缺省信息填充到cinfo结构中以便程序使用。

    (void) jpeg_read_header(&cinfo, TRUE);

此时,常见的可用信息包括图像的宽cinfo.image_width,高cinfo.image_height,色彩空间cinfo.jpeg_color_space,颜色通道数cinfo.num_components等。

4、为解压设定参数,包括图像大小和颜色空间。

比如可以设定解出来的图像的大小,也就是与原图的比例。使用scale_num和scale_denom两个参数,解出来的图像大小就是scale_num/scale_denom,但是IJG当前仅支持1/1, 1/2, 1/4,和1/8这几种缩小比例。

比如要取得1/2原图的图像,需要如下设定:

    cinfo.scale_num=1;cinfo.scale_denom=2;

也可以设定输出图像的色彩空间,即cinfo.out_color_space,可以把一个原本彩色的图像由真彩色JCS_RGB变为灰度JCS_GRAYSCALE。如:

cinfo.out_color_space=JCS_GRAYSCALE;

5、开始解压缩。

根据设定的解压缩参数进行图像解压缩操作。

(void) jpeg_start_decompress(&cinfo);

在完成解压缩操作后,会将解压后的图像信息填充至cinfo结构中。比如,输出图像宽度cinfo.output_width,输出图像高度cinfo.output_height,每个像素中的颜色通道数cinfo.output_components(比如灰度为1,全彩色为3)等。

一般情况下,这些参数是在jpeg_start_decompress后才被填充到cinfo中的,如果希望在调用jpeg_start_decompress之前就获得这些参数,可以通过调用jpeg_calc_output_dimensions()的方法来实现。

6、取数据。

解开的数据是按照行取出的,数据像素按照scanline来存储,scanline是从左到右,从上到下的顺序,每个像素对应的各颜色或灰度通道数据是依次存储,比如一个24-bit RGB真彩色的图像中,一个scanline中的数据存储模式是R,G,B,R,G,B,R,G,B,...,每条scanline是一个JSAMPLE类型的数组,一般来说就是unsigned char,定义于jmorecfg.h中。除了JSAMPLE,图像还定义了JSAMPROW和JSAMPARRAY,分别表示一行JSAMPLE和一个2D的JSAMPLE数组。

在此,我定义一个JSAMPARRAY类型的缓冲区变量来存放图像数据。

    JSAMPARRAY buffer;

然后是计算每行需要的空间大小,比如RGB图像就是宽度×3,灰度图就是宽度×1

    row_stride = cinfo.output_width * cinfo.output_components;

为缓冲区分配空间,这里使用了libjpeg的内存管理器来完成分配。

JPOOL_IMAGE表示分配的内存空间将在调用jpeg_finish_compress,jpeg_finish_decompress,jpeg_abort后被释放,而如果此参数改为JPOOL_PERMANENT则表示内存将一直到JPEG对象被销毁时才被释放。

row_stride如上所说,是每行数据的实际大小。

最后一个参数是要分配多少行数据。此处只分配了一行。

buffer = (*cinfo.mem->alloc_sarray)((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1);

output_scanline表示当前已经读取的行数,如此即可依次读出图像的所有数据,并填充到缓冲区中,参数1表示的是每次读取的行数。

    while(cinfo.output_scanline < cinfo.output_height){(void) jpeg_read_scanlines(&cinfo, buffer, 1);//do something}

7、解压完毕。

    (void) jpeg_finish_decompress(&cinfo);

8、释放资源和退出程序。

    jpeg_destroy_decompress(&cinfo);fclose(infile);

如果不再需要JPEG对象,则使用

    jpeg_destroy_decompress(&cinfo);
或jpeg_destroy(&cinfo);

而如果还希望继续使用JPEG对象,则可使用

    jpeg_abort_decompress(&cinfo);
或jpeg_abort(&cinfo);

完整例程:

//变量定义struct jpeg_decompress_struct cinfo;struct jpeg_error_mgr jerr;FILE * infile;JSAMPARRAY buffer;int row_stride;        //绑定标准错误处理结构cinfo.err = jpeg_std_error(&jerr);
//初始化JPEG对象jpeg_create_decompress(&cinfo);
//指定图像文件if ((infile = fopen("sample.jpg", "rb")) == NULL){
perror("fopen fail");
return;}jpeg_stdio_src(&cinfo, infile);//读取图像信息(void) jpeg_read_header(&cinfo, TRUE);//设定解压缩参数,此处我们将图像长宽缩小为原图的1/2cinfo.scale_num=1;cinfo.scale_denom=2;//开始解压缩图像(void) jpeg_start_decompress(&cinfo);//本程序功能是应用GDI+在客户区绘制图像CClientDC dc(this);Bitmap bm( cinfo.output_width , cinfo.output_height); Graphics graphics(dc.GetSafeHdc());Graphics gdc(&bm);//分配缓冲区空间row_stride = cinfo.output_width * cinfo.output_components;buffer = (*cinfo.mem->alloc_sarray)((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1);
//读取数据while (cinfo.output_scanline < cinfo.output_height){(void) jpeg_read_scanlines(&cinfo, buffer, 1);//output_scanline是从1开始,所以需要减1int line=cinfo.output_scanline-1;for(int i=0;i<cinfo.output_width;i++){//绘制位图,本例中假设读取的sample.jpg图像为RGB真彩色图像//因此,实际上cinfo.output_components就等于3,灰度图则需另作处理bm.SetPixel(i,line,Color(255,(BYTE)buffer[0][i*3],(BYTE)buffer[0][i*3+1],(BYTE)buffer[0][i*3+2]));}}//结束解压缩操作(void) jpeg_finish_decompress(&cinfo);//释放资源jpeg_destroy_decompress(&cinfo);fclose(infile);//在客户区绘制位图graphics.DrawImage(&bm,0,0);

libjpeg库的简单使用使用----jpeg图片解压相关推荐

  1. 使用libjpeg-turbo库中的TurboJPEG API实现图片解压,缩放及压缩功能

    概述:前一篇博客中说到libjpeg-turbo的使用,有一些错误也在前篇博客中纠正了,现在呢,就用TurboJPEG API实现图片的解压,缩放,压缩. 1,直接上代码(简单粗暴,重要代码都加了注释 ...

  2. libjpeg库的简单使用,rgb565与rgb888互转,以及色块的寻找

    最近用的摄像头OV2640摄像头,支持RGB565.JPEG.YUV和YCbCr格式的输出,想要对采集的图像进行色块识别,这样一般需要用到RGB格式的输出会比较好处理,数字图像处理中常用的采用模型是R ...

  3. 一款动态跑路html源码,简单实用,上传解压就完事了

    介绍: 一款动态跑路源码,简单实用,上传解压就完事了 搭建教程: 1.领取主机 2.二级域名 3.上传源码到主机文件夹,解压 4.绑定域名,搭建完成 网盘下载地址: http://kekewangLu ...

  4. JPEG图像压缩解压算法——C++实现

    兹于2017年11月,应<多媒体技术基础>课程实验的要求,本人就基于JPEG图像压缩解压算法做了较为深入的理解,用C++语言实现JPEG图像压缩解压算法. JPEG图像压缩解压算法 一.实 ...

  5. android http zlib,利用zlib库对HTTP收到的gzip数据解压

    1.首先说为什么采用zlib解压,因为zlib可以解压内存数据. 2.下载zlib库后,自己在projcts目录里面根据需要编译lib库 3.静态链接只需要zlib.h ;zconf.h;zlib.l ...

  6. requests库+正则表达式--简单爬虫实例--美女图片篇

    正则表达式–简单爬虫实例–4K美女篇 文章目录 section1:声明 section2:下载链接分析 section3:代码编写 1.导入板块 2.构造请求 3.正则表达式的构造 4.数据处理 5. ...

  7. Python 技术篇-用zipfile库进行zip文件的压缩与解压实例演示,python压缩本地文件夹为zip文件并保留目录结构

    首先给大家演示下 zip 文件的解压方法. import zipfiledef zip_extract_to(path_zip, path_aim):'''作用:解压压缩包参数一:压缩包位置参数二:解 ...

  8. libjpeg 库的安装

    libjpeg 库的安装 一.环境简介:ubuntu11.04    以root用户登陆(对不是以root用户登陆的,这不影响!) 二.安装 1.到 libjpeg 的官网下载 libjpeg 的 U ...

  9. VS2015编译libjpeg库

    参考资料: 1.http://blog.csdn.net/joeblackzqq/article/details/42264143 2.http://www.cnblogs.com/summerRQ/ ...

最新文章

  1. QT事件 sendEvent()、postEvent()和QObject::customEvent()
  2. Lazada代运营怎么样?需不需要找?如何选择一家靠谱的公司
  3. UE4入门学习3:GamePlay框架
  4. 单例模式---懒汉模式与饿汉模式
  5. djano 模型查询
  6. JDK8新特性之重复注解
  7. win10系统能做域服务器吗,Win10 LTSC 加入 Windows Server 2019 域服务器
  8. SpringCloud 入门教程(三): 配置自动刷新
  9. 【opencv图像基础】图像常见的通道模式:RGB、YUV、HSV
  10. 深入解析常量池与装拆箱机制
  11. @程序员,让8年京东架构师为你解析云原生监控和日志解决方案!
  12. matlab重复线性回归,(MATLAB)一元线性回归和多元线性回归
  13. 京东搜索排序在线学习的 Flink 优化实践
  14. 一致性hash算法的应用研究学习
  15. 3dsMax中Vray渲染器材质参数使用及5种材质展示
  16. 计算机桌面软件图标没了,手把手教你电脑桌面图标都不见了怎么办
  17. x58服务器主板装win7系统,技嘉Z390主板重装win7方法|Z390主板Bios设置及安装win7图文教程...
  18. java导出可运行文件格式,|java导出excel,excel打不开,报文件格式无效,怎么解决!...
  19. systemd-journald日志进程介绍
  20. 54 计算机与信息科学类,关于信息科学与技术学院自动化类及计算机类2019级大类分专业学生名单公示的通知...

热门文章

  1. 视频互动直播软件开发中的连麦问题分析 1
  2. window下安装git flow
  3. 如何在CST仿真软件中开启GPU加速
  4. 0Ω电阻到底能过多大电流啊
  5. 微软明年春季发布 Win 10X;教育部将编程教育纳入中小学课程
  6. 用什么软件测试ipad性能,数码专栏 篇一:关于2018款ipad办公性能测试,真得适合吗?...
  7. MPAndroidChart项目实战(一)——实现对比性柱状图
  8. 关于数学计算机手抄报简单的,数学手抄报简单又漂亮
  9. word2007插入分节符(奇数页)后自动变成分节符(下一页)的解决办法
  10. 小米13 和红米k60 pro 参数对比哪个值得买