libjpeg库的简单使用使用----jpeg图片解压
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图片解压相关推荐
- 使用libjpeg-turbo库中的TurboJPEG API实现图片解压,缩放及压缩功能
概述:前一篇博客中说到libjpeg-turbo的使用,有一些错误也在前篇博客中纠正了,现在呢,就用TurboJPEG API实现图片的解压,缩放,压缩. 1,直接上代码(简单粗暴,重要代码都加了注释 ...
- libjpeg库的简单使用,rgb565与rgb888互转,以及色块的寻找
最近用的摄像头OV2640摄像头,支持RGB565.JPEG.YUV和YCbCr格式的输出,想要对采集的图像进行色块识别,这样一般需要用到RGB格式的输出会比较好处理,数字图像处理中常用的采用模型是R ...
- 一款动态跑路html源码,简单实用,上传解压就完事了
介绍: 一款动态跑路源码,简单实用,上传解压就完事了 搭建教程: 1.领取主机 2.二级域名 3.上传源码到主机文件夹,解压 4.绑定域名,搭建完成 网盘下载地址: http://kekewangLu ...
- JPEG图像压缩解压算法——C++实现
兹于2017年11月,应<多媒体技术基础>课程实验的要求,本人就基于JPEG图像压缩解压算法做了较为深入的理解,用C++语言实现JPEG图像压缩解压算法. JPEG图像压缩解压算法 一.实 ...
- android http zlib,利用zlib库对HTTP收到的gzip数据解压
1.首先说为什么采用zlib解压,因为zlib可以解压内存数据. 2.下载zlib库后,自己在projcts目录里面根据需要编译lib库 3.静态链接只需要zlib.h ;zconf.h;zlib.l ...
- requests库+正则表达式--简单爬虫实例--美女图片篇
正则表达式–简单爬虫实例–4K美女篇 文章目录 section1:声明 section2:下载链接分析 section3:代码编写 1.导入板块 2.构造请求 3.正则表达式的构造 4.数据处理 5. ...
- Python 技术篇-用zipfile库进行zip文件的压缩与解压实例演示,python压缩本地文件夹为zip文件并保留目录结构
首先给大家演示下 zip 文件的解压方法. import zipfiledef zip_extract_to(path_zip, path_aim):'''作用:解压压缩包参数一:压缩包位置参数二:解 ...
- libjpeg 库的安装
libjpeg 库的安装 一.环境简介:ubuntu11.04 以root用户登陆(对不是以root用户登陆的,这不影响!) 二.安装 1.到 libjpeg 的官网下载 libjpeg 的 U ...
- VS2015编译libjpeg库
参考资料: 1.http://blog.csdn.net/joeblackzqq/article/details/42264143 2.http://www.cnblogs.com/summerRQ/ ...
最新文章
- QT事件 sendEvent()、postEvent()和QObject::customEvent()
- Lazada代运营怎么样?需不需要找?如何选择一家靠谱的公司
- UE4入门学习3:GamePlay框架
- 单例模式---懒汉模式与饿汉模式
- djano 模型查询
- JDK8新特性之重复注解
- win10系统能做域服务器吗,Win10 LTSC 加入 Windows Server 2019 域服务器
- SpringCloud 入门教程(三): 配置自动刷新
- 【opencv图像基础】图像常见的通道模式:RGB、YUV、HSV
- 深入解析常量池与装拆箱机制
- @程序员,让8年京东架构师为你解析云原生监控和日志解决方案!
- matlab重复线性回归,(MATLAB)一元线性回归和多元线性回归
- 京东搜索排序在线学习的 Flink 优化实践
- 一致性hash算法的应用研究学习
- 3dsMax中Vray渲染器材质参数使用及5种材质展示
- 计算机桌面软件图标没了,手把手教你电脑桌面图标都不见了怎么办
- x58服务器主板装win7系统,技嘉Z390主板重装win7方法|Z390主板Bios设置及安装win7图文教程...
- java导出可运行文件格式,|java导出excel,excel打不开,报文件格式无效,怎么解决!...
- systemd-journald日志进程介绍
- 54 计算机与信息科学类,关于信息科学与技术学院自动化类及计算机类2019级大类分专业学生名单公示的通知...
热门文章
- 视频互动直播软件开发中的连麦问题分析 1
- window下安装git flow
- 如何在CST仿真软件中开启GPU加速
- 0Ω电阻到底能过多大电流啊
- 微软明年春季发布 Win 10X;教育部将编程教育纳入中小学课程
- 用什么软件测试ipad性能,数码专栏 篇一:关于2018款ipad办公性能测试,真得适合吗?...
- MPAndroidChart项目实战(一)——实现对比性柱状图
- 关于数学计算机手抄报简单的,数学手抄报简单又漂亮
- word2007插入分节符(奇数页)后自动变成分节符(下一页)的解决办法
- 小米13 和红米k60 pro 参数对比哪个值得买