求大神写一个用哈夫曼编码压缩比实现对图像的压缩程序

怎样用C语言实现霍夫曼编码对图像的无损压缩?怎么输入未压缩图像跟输出压缩图像?能具体点么_百度知道
怎样用C语言实现霍夫曼编码对图像的无损压缩?怎么输入未压缩图像跟输出压缩图像?能具体点么
因为很少用百度知道,财富值很少,请帮我一下
我有更好的答案
`你的目的是什么?压缩还是加密还是转码呀???
是压缩,就是用霍夫曼编码进行重新编码,要怎么做才能把图像转换成C语言里的编码呢?还有压缩完成后怎么完成图像的输出?能帮忙解答吗?
倒序回答:能帮忙解答吗?能!压缩完成后怎么完成图像的输出?首先说压缩,既然是压缩就是要以破坏原有的图像编码为前提的,也就是说你压缩后的文件就已经不再是图像了,如果要再次使用一个要先解压才行.不论是解压成为文件还是解压成内存,都要解压.要怎么做才能把图像转换成C语言里的编码呢?这个问题我有点不明白你想问什么,你的意思是怎么把文件变成霍夫曼编码中的字符串吗?如果是的话就真接打开文件读成Buffer就OK了如果不是就再追问吧
嗯,就是指怎么变成霍夫曼编码里的字符串,要怎么把文件读成buffer呢?实在是抱歉。。能给个具体点的建议吗,buffer应该是缓存吧?我还是刚接触c,不好意思麻烦你了。还有就是,图像压缩可能与你认为的有些差别,要再次输出一副图像,这样的话可能算是转码吧,不是把图像压缩成重新编码的字符串
我还是倒序回答吧,1.图像压缩一般是指将没有压缩的图片进行一定的处理,变成另一种体积较小的图片,图像压缩一般分为两种:有损和无损,举例来说JPG系列就是典型的有损压缩图像,而PNG就是无损压缩的图像,BMP就是没有压缩的位图.像这种压缩也可以理解为转码.但也是真的压缩了.2.既然你都说是C语言了,我就用C语言的办法给你写代码吧:FILE*
pFile = NULL;
// 定义文件操作用的结构体指针pFile = fopen("C:\\1.bmp","rb"); // 打开文件"C:\1.bmp",以字节只读打开文件long
nFileSize = 0;
// 定义存文件大小的变量fseek(pFile,0,SEEK_END);
// 将文件操作的位置指向文件结尾nFileSize = ftell(pFile);
// 得到文件操作位置(由于上面已经指向文件结尾所以nFileSize为文件大小)char* pBuf = NULL;
// 定义存内容用的内存Buffer指针pBuf = (char*)malloc(nFileSize); // 向系统申请文件大小个字节内存fread(pBuf,nFileSize,1,pFile); // 读出内容fclose(pFile);
// 关闭文件到这pBuf就是变成霍夫曼编码里的&字符串&了.而nFileSize就是长度注:因为pBuf不是真正的字符串,而是内存Buffer所以不要用strlen()来得到长度,
采纳率:72%
为您推荐:
其他类似问题
霍夫曼编码的相关知识
换一换
回答问题,赢新手礼包
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。您所在位置: &
&nbsp&&nbsp&nbsp&&nbsp
基于哈夫曼编码图像压缩系统的设计与实现.pdf 51页
本文档一共被下载:
次 ,您可全文免费在线阅读后下载本文档。
下载提示
1.本站不保证该用户上传的文档完整性,不预览、不比对内容而直接下载产生的反悔问题本站不予受理。
2.该文档所得收入(下载+内容+预览三)归上传者、原创者。
3.登录后可充值,立即自动返金币,充值渠道很便利
你可能关注的文档:
··········
··········
山东理工大学硕士学位论文
独 创 性 声 明
本人声明所呈交的论文是我个人在导师指导下进行的研究工作及取得的研究成
果。尽我所知,除了文中特别加以标注和致谢的地方外,论文中不包含其他人已经
发表或撰写过的研究成果,也不包含为获得山东理工大学或其它教育机构的学位或
证书而使用过的材料。与我一同工作的同志对本研究所做的任何贡献均已在论文中
作了明确的说明并表示了谢意。
研究生签名:
关于论文使用授权的说明
本人完全了解山东理工大学有关保留、使用学位论文的规定,即:学校有权保
留送交论文的复印件和磁盘,允许论文被查阅和借阅;学校可以用不同方式在不同
媒体上发表、传播学位论文的全部或部分内容,可以采用影印、缩印或扫描等复制
手段保存、汇编学位论文。
(保密的学位论文在解密后应遵守此协议)
研究生签名:
导 师 签 名:
山东理工大学硕士学位论文
图像压缩技术是目前计算机应用领域的一项热门技术。随着计算机技术、现代通信
技术、网络技术和信息处理技术的迅速发展,图像作为一种重要的信息载体已经成为应
用最广泛的信息表现形式之一。但是由于未经处理的图像本身数据量非常大,这给图像
的传输、存储及加工处理等方面带来了极大的困难,要消除上述三种图像应用中的困难,
关键对图像进行压缩。图像实现压缩的过程要付出较大的计算量,但相对于图像压缩的
意义又是非常值得的。图像实现压缩的意义在于减少数据存储量,节省存储数据时的存
储空间和CPU处理数据的时间;降低数据率以减少传输时的使用带宽,节省传输时间;
压缩图像的信息量,便于特征抽取,为识别做准备。图像数据能够实现压缩主要有两个
方面的原因:一是图像数据中有许多冗余,包括时间冗余、空间冗余等,用某种数学的
方法来表示图像使原始图像数字化从而消除冗余,用这种方式表示的图像还能恢复到图
像的原始状态属于无损压缩范畴;二是利用人眼的生理因素,人眼对图像的细节和某些
颜色的辨别能力存在着一个极限,把超过这个极限的部分去掉,也可以达到压缩目的,
但这种方式表示的图像数据有丢失不能恢复到图像的原始状态,属于有损压缩范畴。本
文主要研究无损压缩的原理和实现方法。本文首先介绍了图像压缩技术的背景、发展历
史和图像压缩的基本原理和图像能够实现压缩的理论依据以及图像压缩的分类应用,并
对图像压缩编码的相关研究现状进行了综述性分析,然后对基于哈夫曼编码算法的图像
压缩方法及具体实现进行研究,其中重点介绍了哈夫曼(Huffman)编码的原理和算法及
其衍生算法,并对几种不同的压缩算法进行了简单的比较,得出结论哈夫曼编码能够实
现对图像数据的无损压缩,并且得出哈夫曼编码在有着广泛应用的同时已不再是压缩算
法的全部,而经常与其它的压缩算法相结合被当作最终的编码方法,如JPEG压缩算法。
本文充分利用哈夫曼编码简洁方便的特性,摒弃了传统的JPEG压缩算法中要进行哈夫曼
编码前先进行图像转换、DCT 变换等复杂的过程,结合 BMP 图像的结构和特点,提出了
一种更为简洁的可以实现无损压缩的哈夫曼编码方法,即单纯基于哈夫曼编码算法实现
对256色 BMP图像数据部分的压缩方法。该算法有两个互逆过程:压缩和解压缩。针对
256色 BMP图像,要实现压缩必须对新编码进行按位存储,由于选择的开发工具是Visual
Basic 6.0,它没有像C语言等开发工具一样的位操作或移位运算功能,通过乘以2、除
以2来实现等价的左移、右移操作,实现了按位存储,进而实现压缩过程。解压缩过程
与之相反。最后,利用VB6.0作为开发工具,依托哈夫曼编码图像压缩理论开发了一个
能够对256色 BMP图像进行压缩和解压缩的软件系统,并对该系统作了简单的测试分析,
得到了良好的压缩效果,说明该算法是有效可行的,另外,该软件系统与其它同类产品
相比界面友好、操作简单,具有一定的实用性。
关键词:哈夫曼;熵;压缩;解压缩;编码;解码;冗余;二叉树
山东理工大学硕士学位论文
Nowadays, image compression technology is a h
正在加载中,请稍后...基于哈夫曼编码的图像压缩技术研究_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
基于哈夫曼编码的图像压缩技术研究
&&数据压缩
阅读已结束,下载文档到电脑
想免费下载本文?
定制HR最喜欢的简历
你可能喜欢利用哈夫曼编码实现压缩和解压缩_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
利用哈夫曼编码实现压缩和解压缩
阅读已结束,下载文档到电脑
想免费下载本文?
定制HR最喜欢的简历
下载文档到电脑,方便使用
还剩9页未读,继续阅读
定制HR最喜欢的简历
你可能喜欢基于哈夫曼编码的压缩解压程序(C 语言) - keke2014 - 博客园
comments(17)
trackbacks(0)
&这个程序是研一上学期的课程大作业。当时,跨专业的我只有一点 C 语言和数据结构基础,为此,我查阅了不少资料,再加上自己的思考和分析,实现后不断调试、测试和完善,耗时一周左右,在
完成。虽然这是一个很小的程序,但却是我完成的第一个程序。
源码托管在 Github:
以下为完整的作业报告:
一、问题描述:
名称:基于哈夫曼编码的文件压缩解压
目的:利用哈夫曼编码压缩存储文件,节省空间
输入:任何格式的文件(压缩)或压缩文件(解压)
输出:压缩文件或解压后的原文件
功能:利用哈夫曼编码压缩解压文件
性能:快速
二、问题的初步讨论:
为了建立哈夫曼树,首先扫描源文件,统计每类字符出现的频度(出现的次数),然后根据字符频度建立哈夫曼树,接着根据哈夫曼树生成哈夫曼编码。再次扫描文件,每次读取8bits,根据&字符&编码&表,匹配编码,并将编码存入压缩文件,同时存入编码表。解压时,读取编码表,然后读取编码匹配编码表找到对应字符,存入文件,完成解压。
三、总的UML协同图:
四、文件读取方式和处理单元的分析:
压缩解压的第一步就是读取文件,为了能够处理任何格式的文件,采用二进制方式读写文件。以一个无符号字符(unsigned char)的长度8位为处理单元,最多有256(0~255)种组合,即256类字符。
五、字符频度扫描的分析:
要建立哈夫曼树,先要得到各类字符的频度,我想到了两种扫描方案:
1、利用链表存储,每扫描到一类新字符就动态分配内存;
2、利用数组,静态分配256个空间,对应256类字符,然后用下标随机存储。
链表在需要时才分配存储空间,可以节省内存,但是每加入一个新字符都要扫描一次链表,很费时;考虑到仅有256个字符种类,不是很多,使用静态数组,不会造成很大的空间浪费,而可以用数组的下标匹配字符,不需扫描数组就可以找到每类字符的位置,达到随机存储的目的,效率有很大的提高。当然,不一定每类字符都出现,所以,统计完后,需要排序,将字符频度为零的结点剔除。
我定义的数组类似这样:Node array[CHAR_KINDS],其中CHAR_KINDS为8位无符号字符对应的256(0~255)种不同组合,这样每扫描到一个字符,直接将字符作为下标,就可以找到字符的位置。
六、建立哈夫曼树的分析:
哈夫曼树为二叉树,树结点含有权重(在这里为字符频度,同时也要把频度相关联的字符保存在结点中)、左右孩子、双亲等信息。
考虑到建立哈夫曼树所需结点会比较多,也比较大,如果静态分配,会浪费很大空间,故我们打算用动态分配的方法,并且,为了利用数组的随机访问特性,也将所需的所有树节点一次性动态分配,保证其内存的连续性。另外,结点中存储编码的域,由于长度不定,也动态分配内存。
6.1、这时,针对上面的字符扫描结点就要做一些改动:
将其定义成临时结点TmpNode,这个结点仅保存字符及对应频度,也用动态分配,但是一次性分配256个空间,统计并将信息转移到树结点后,就将这256个空间释放,既利用了数组的随机访问,也避免了空间的浪费。
七、生成哈夫曼编码的分析:
每类字符对应一串编码,故从叶子结点(字符所在结点)由下往上生成每类字符对应的编码,左&0&,右&1&。为了得到正向的编码,设置一个编码缓存数组,从后往前保存,然后从前往后拷贝到叶子结点对应编码域中,根据上面&建立哈夫曼树的协商&的约定,需要根据得到的编码长度为编码域分配空间。对于缓存数组的大小,由于字符种类最多为256种,构建的哈夫曼树最多有256个叶子结点,树的深度最大为255,故编码最长为255,所以分配256个空间,最后一位用于保存结束标志。
八、文件压缩的分析:
上面协定以8位的字符为单元编码,这里压缩当然也以8位为处理单元。
首先将字符及种类和编码(编码表)存储于压缩文件中,供解压时使用。
然后以二进制打开源文件,每次读取一个8位的无符号字符,循环扫描匹配存储于哈夫曼树节点中的编码信息。
由于编码长度不定,故需要一个编码缓存,待编码满足8位时才写入,文件结束时缓存中可能不足8位,在后面补0,凑足8位写入,并将编码的长度随后存入文件。
在哈夫曼树节点中,编码的每一位都是以字符形式保存的,占用空间很大,不可以直接写入压缩文件,故需要转为二进制形式写入;至于如何实现,可以定义一个函数,将保存编码的字符数组转为二进制,但是比较麻烦,效率也不高;正好,可以利用C语言提供的位操作(与、或、移位)来实现,每匹配一位,用&或&操作存入低位,并左移一位,为下一位腾出空间,依次循环,满足8位就写入一次。
8.1、压缩文件的存储结构:
结构说明:字符种类用来判断读取的字符、频度序偶的个数,同时用来计算哈夫曼结点的个数;文件长度用来控制解码生成的字符个数,即判断解码结束。
九、文件解压的分析:
以二进制方式打开压缩文件,首先将文件前端的字符种类数读取出来,据此动态分配足够空间,然后将随后的字符&编码表读取处理保存到动态分配的结点中,然后以8位为处理单元,依次读取随后的编码匹配对应的字符,这里对比编码依然用在文件压缩中所用的方法,就是用C语言的位操作,同0x80与操作,判断8bits字符的最高位是否为&1&,对比一位后,左移一位,将最高位移除,次高位移到最高位,依次对比。这次是从编码到字符反向匹配,与压缩时有一点不同,需要用读取的编码逐位与编码表中的编码进行对比,对比一位后,增加一位再对比,而且每次对比都是一个循环(与每个字符的编码对比),效率很低。
于是,我思考另外的方法,可以将哈夫曼树保存到文件中,解码时,从树根到叶子对比编码,只要一次遍历就可以找到编码对应的存于叶子结点中的字符,极大提高了效率。
然而,我们发现树结点中有字符、编码、左右孩子、双亲,而且孩子和双亲还必须是整型的(树节点最多为256*2-1=511个),占用空间很大,会导致压缩文件变大,这是不可取的,因为我们的目的就是压缩文件。
我们进一步考虑,可以仅存储字符及对应频度(频度为unsigned long,一般情况下与int占用空间一样,同为4个字节),解码时读取数据重建哈夫曼树,这样就解决了空间问题。
虽然重建哈夫曼树(双重循环,每个循环的次数最大为511)也要花费一定的时间,但是相对上面的与编码表匹配(每位编码都要循环匹配所有字符(最多为256种)一次,而总的编码位数一般很大,且随着文件变大而增长)所花费的时间更少。
9.1由于解压的方式变了,在这里要对上面的协商作一些修改:
1、修改后的总UML协同图:
2、在文件压缩时,就不需要保存编码表,改为保存字符及对应权重。
3、在文件压缩时,处理最后不足8位的编码后,不再需要保存编码的长度,因为解压时从树根向下匹配,到达叶子就停止(所有叶子结点都在连续分配的树结点空间的低端,故可以用结点下标判断是否到达叶子结点),不会超过而读取最后的无效编码。
十、定义所需类:
10.1、文件压缩所需类:
行为说明:char_kinds保存出现的字符种类;char_temp用来保暂存字符;code_buf暂存匹配出来的编码;compres()是主压缩函数,接收两个文件名,一个输入,可以是任何格式的待压缩文件,一个输出,为压缩后的编码文件;
10.2、文件解压所需类:
行为说明:char_kinds保存出现的字符种类;char_temp用来保暂存字符;root保存解码时的当前结点索引,用来判断是否达到叶子结点;extract()是主压缩函数,接收两个文件名,一个输入,为压缩后的编码文件,一个输出,为解码后的原文件;
10.3、其他重要类:
行为说明:
1、tmp_nodes用来保存字符频度,动态一次性分配256个空间,统计后删除;CalChar()用于生成8位的256个字符及对应频度(出现次数);
2、node_num保存树结点总数,CreateTree()建立哈夫曼树,select()函数用来找最小的两个结点;
3、huf_node树结点用来保存编码信息,HufCode()生成哈夫曼编码;
10.4、类的关联图:
行为说明:CreateTree()和HufCode()供compress调用,前者建立哈夫曼树,后者生成哈夫曼编码;CreateTree()供extrac()调用,重建哈夫曼树,用于解码;
十一、编码行为状态图:
后来我在初步编码时,发现一些问题:解码后无法得到完全正确的源文件,经过排查,发现以EOF判断压缩文件的结束不可取,因为压缩文件是二进制文件,而EOF一般用来判断非二进制文件的结束,所以我们加入了文件长度来控制。
11.1、于是上面的协商需要一些改动:
1、修改后的字符统计类:
2、修改后的文件压缩类:
3修改后的编码行为状态图:
十二、函数实现:
12.1、实现语言及编码环境:
实现语言:C语言,兼容嵌入式,运行效率高
编码环境:XP+VS2010(debug模式)
12.2、结构体及函数定义:
两个重要的结点结构体:
三个函数用于建立哈夫曼树和生成哈夫曼编码:
两个主要函数&&压缩解压函数:
12.3、函数说明:
12.3.1、其他函数:
Select函数供CreateTree函数调用,找两个最小的结点,找到第一个后需要将其parent设为&1&(初始化后为&0&)表明此结点已被选中:
建立哈夫曼树,每次用select()函数找两个最小结点:
生成哈夫曼编码,由叶子到根反向生成编码,左&0&,右&1&,每个code域的内存动态分配:
12.3.2、压缩函数中的几个部分的说明:
动态分配256个暂存结点,用下标索引统计字符频度:
这里以feof来判断文件结束,是由于eof判断的文件类型比较局限,而feof在读完最后一个字节之后,再次读文件时才会设置结束标志,所以需要在while循环之前读一次,然后每次在循环的最后读取文件,这样可以正确判断文件结束;以位操作来匹配编码,每次存入最低位,然后左移一位,依次循环处理,满8位保存一次:
最后缓冲中不足8位,补0凑足8位(左移):
12.3.3、解压函数中的说明:
压缩文件为二进制文件,feof在这里无法正确判断结束,故用一个死循环处理编码,以压缩时存储的文件长度来控制循环的结束。每当root小于char_kinds,就匹配到了一个字符,是因为字符的下标范围是0~char_kinds-1。
十三、程序健壮性考虑:
13.1、字符种类为&1&:
当字符种类为&1&时,只有一个哈夫曼结点,无法构造哈夫曼编码,但是可以直接处理,依次保存字符种类数、字符、字符频度(此时就是文件长度)即可,解压时仍然先读取字符种类数,为&1&则特殊处理,读取字符和频度(此时就是文件长度),利用频度控制循环,输出字符到文件即可,此时压缩文件的存储结构为:
在压缩函数前部加入特殊情况的判断和处理:
在解压函数前部加入特殊情况判断和处理:
13.2、输入文件不存在:
由于压缩或解压时,输入文件必须是存在的,而用户可能会输错,因此有必要加入输入文件的存在性进行判断,防止文件不存在而导致程序异常退出:
1、将压缩解压的返回值改为int:
2、在压缩和解压函数中加入:
3、在main函数中加入压缩解压函数是否异常退出的判断:
十四、系统测试:
14.1、测试流程图:
14.2、代码运行测试:
14.2.1、使用说明:
(编译链接生成的可执行文件为:hufzip.exe)
双击hufzip.exe运行,输入所选择操作类型的数字代号:
1:compress(压缩)
2:extract(解压)
3:quit(退出)
然后提示输入源文件和目标文件,可以输入完整的路径名加文件名,也可以仅输入一个文件名(默认在当前运行目录下寻找),如果不小心输错源文件名或源文件不存在,将提示出错,然后可以再次输入,如下图所示:
14.2.2、测试的几个文件:
&1.txt&中为全为字符&a&(共个),由于只有一种字符,压缩文件只保存了字符种类(4byte)、字符(1byte)和字符频度(4byte),故为9字节,控制台及文件压缩情况如下(1.txt.hufzip为压缩文件,1.hufzip.txt为解压后的文件):
&2.txt&为0~255的整数,其中0出现1次,1出现2次,&&,255出现256次,其控制台及压缩情况如下(2.txt.hufzip为压缩文件,2.hufzip.txt为解压后的文件):
&3.doc&为一个随意的word文档,其控制台及压缩情况如下(3.doc.hufzip为压缩文件,3.hufzip.doc为解压后的文件):
&4.jpg&是一个图像文件,输入绝对路径对4.jpg进行压缩,其控制台及压缩情况如下(4.jpg.hufzip为压缩文件,4.hufzip.jpg为解压后的文件):
14.2.3、由上面的几种文件的压缩前后的对比可以得出:
哈夫曼编码对文本文件,一般可以达到大约2:1的压缩比,特别是有规律的文本文件,可以达到高于2:1的压缩比,而对于图像等特殊文件压缩比几乎为1:1,效果不理想。
十五、总结:
通过这一个压缩和解压程序的设计,我学习了UML的使用,提升了编码能力,提升了调试能力,总之,受益匪浅。}

我要回帖

更多关于 哈夫曼编码压缩率 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信