导航:首页 > 文件处理 > 哈夫曼图片压缩

哈夫曼图片压缩

发布时间:2023-01-11 23:47:04

Ⅰ Huffman编码不适合图像压缩么,为什么。有相关的资料么。能给我看看不QQ504278770

下面是我从网上搜索到的资料,希望对你有帮助。

1.哈夫曼图像压缩算法引言

随着网络与多媒体技术的兴起,人们需要存储和传输的数据越来越多,数据量越来越大,以前带宽有限的传输网络和容量有限的存储介质难以满足用户的需求。

特别是声音、图像和视频等媒体在人们的日常生活和工作中的地位日益突出,这个问题越发显得严重和迫切。如今,数据压缩技术早已是多媒体领域中的关键技术之一。

Huffman(哈夫曼)算法在上世纪五十年代初提出来了,它是一种无损压缩方法,在压缩过程中不会丢失信息熵,而且可以证明Huffman算法在无损压缩算法中是最优的。Huffman原理简单,实现起来也不困难,在现在的主流压缩软件得到了广泛的应用。对应用程序、重要资料等绝对不允许信息丢失的压缩场合,Huffman算法是非常好的选择。

2.哈夫曼图像压缩算法原理

Huffman编码是1952年由Huffman提出的对统计独立信源能达到最小平均码长的编码方法。这一年,他发表了着名论文“A Method for the Construction of Minimum Rendancy Codes”,即最短冗余码的构造方法.之后,Huffman编码及其一些改进方法一直是数据压缩领域的研究热点之一。

Huffman码是一种变长码,其基本思想是:先统计图像(已经数字化)中各灰度出现的概率,出现概率较大的赋以较短的码字,而出现概率较小的则赋以较长的码字。我们可以用下面的框图来表示Huffman编码的过程:

在整个编码过程中,统计图像各灰度级出现的概率和编码这两步都很简单,关键的是Huffman树的构造。不但编码的时候需要用到这颗树,解码的时候也必须有这颗树才能完成解码工作,因此,Huffman树还得完整的传输到解码端。

Huffman树的构造可以按照下面图2的流程图来完成。首先对统计出来的概率从小到大进行排序,然后将最小的两个概率相加;到这儿的时候,先把已经加过的两个概率作为树的两个节点,并把他们从概率队列中删除;然后把相加所得的新概率加入到队列中,对这个新队列进行排序。

如此反复,直到最后两个概率相加为1的时候停止。这样,Huffman树就建立起来了。

3. 哈夫曼图像压缩算法软件实现

这儿,我们以Turbo C为例来说明软件实现Huffman图像压缩算法的一些关键技术。

为了叙述方便,我们不妨假设处理的图像的灰度级变化范围从0到255,即具有256个灰度级。我们先来统计输入图像的概率,实际上是要统计各个灰度级在整幅图像中出现的次数。为此,我们先定义一个具有256个元素的数组。

然后对输入图像信号进行扫描,每出现一个灰度,就把它存入实现定义好的一个数组中的相应元素中(让这个元素的值自增1)。最后,通过读取数组中各元素的值就可以求出各个灰度出现的频数。

接下来就该构造Huffman树了。为了构造Huffman树,我们要用到C语言中链表的概念。我们必须用一个结构体来表示Huffman树的节点。对于每个节点而言我们需要这样几个信息:本节点的权重(就是灰度的频数)、指向父节点的指针和分别指向左右子叶节点的指针。于是,我们可以定义这样一个结构体:

Struct Node{

Floatweight;

Node * father;

Node * left;

Node * right;}Huffman_Node

我们需要先确定权最低的两个自由结点,这将是最初的left和right节点。然后建立这两个结点的父结点,并让它的权等于这两个结点的权之和。

接着将这个父结点增加到自由结点的序列中,而两个子结点则从序列中去掉。重复前面的步骤直到只剩下一个自由结点,这个自由结点就是Huffman树的根。

Huffman编码树作为一个二叉树从叶结点逐步向上建立。Huffman树建立好以后,为了把权、概率等数值转化码字,我们还得对整个Huffman树进行扫描。请注意,在建立Huffman树的时候,我们是从树叶开始的,而在对Huffman树分配码字的时候却刚好相反,是从树根开始,沿着各个树枝的走向“顺藤摸瓜”似的对各个系数进行编码。

对于一个节点的两个子节点(left和right),其中一个节点对应的位为0,而另一个结点则人为地设置成为l。解码的时候也是完全相同的一颗Huffman树完成的。下面的循环是实现压缩的关键语句之一[ 1 ]。

for (i = length-1; i >= 0; ――i) {

if ((current_code >> i) & 1)

thebyte |= (char) (1 << curbit);

if (--curbit < 0) {

putc (thebyte, ofile);

thebyte = 0;

curbyte++;

curbit = 7;

}

}

注意:这几行代码执行了数据压缩的功能,但是还没有生成编码和解码所需要的代码表。

4.哈夫曼图像压缩算法性能评价

我们主要从三方面[ 2 ]来评价Huffman的性能:

(1)压缩比的大小;

(2)恢复效果的好坏,也就是能否尽可能的恢复原始数据;

(3)算法的简单易用性以及编、解码的速度。

首先分析一下对压缩比的影响因素(不同的着作中对压缩比的定义不尽相同,这儿我们采用如下定义:压缩比等于压缩之前的以比特计算的数据量比上压缩之后的数据量)。对于Huffman编码来说,我们因为要用额外的位保存和传输Huffman树而“浪费”掉一些存储位,也就是说,为了编、解码的方便,我们把本已减少的数据量又增加了一些。

如果文件比较大的话,这一点多余的数据根本算不了什么,所占比例很小。但是,如果压缩的文件本来就很小的话,那么这笔数据就很可观了。一般来说,经典的Huffman算法的压缩比不是很高,这是无损压缩的“通病”。

第二点就不用说了,由于它是无损压缩,能够完全恢复压缩之前图像的本来面貌。

最后,让我们来分析一下Huffman压缩方法的速度问题。大家在第三节中已经看到了,在压缩的过程中,我们进行了两次扫描,第一次是为了统计各个灰度出现的频数而扫描整幅图像,第二次则是为了分配码字而扫描整个Huffman树。

这样一来,对较大的文件进行编码时,频繁的磁盘读写访问必然会降低数据编码的速度,如果用于网络的话,还会因此带来一些延时,不利于实时压缩和传输。另外,Huffman算法的编码和解码的速度是不对称的,解码快于编码,因为解码不需要生成Huffman树的环节。

5.图像压缩算法结束语

Huffman算法目前已经得到了广泛的应用,软件和硬件都已经实现。基于Huffman经典算法的缺陷,不少人提出了一些自适应算法。前面的算法中,Huffman树是整个图像全部输入扫描完成后构造出来的,而自适应算法(或称动态算法)则不必等到全部图像输入完成才开始树的构造,并且可以根据后面输入的数据动态的对Huffman树进行调整。实际上,实用的Huffman树都是经过某种优化后的动态算法。

网络资源

Ⅱ 基于线性预测和huffman码的无失真图像压缩码编

哈夫曼编码(Huffman Coding)是一种编码方式,以哈夫曼树—即最优二叉树,带权路径长度最小的二叉树,经常应用于数据压缩。 在计算机信息处理中,“哈夫曼编码”是一种一致性编码法(又称"熵编码法"),用于数据的无损耗压缩。这一术语是指使用一张特殊的编码表将源字符(例如某文件中的一个符号)进行编码。这张编码表的特殊之处在于,它是根据每一个源字符出现的估算概率而建立起来的(出现概率高的字符使用较短的编码,反之出现概率低的则使用较长的编码,这便使编码之后的字符串的平均期望长度降低,从而达到无损压缩数据的目的)。这种方法是由David.A.Huffman发展起来的。 例如,在英文中,e的出现概率很高,而z的出现概率则最低。当利用哈夫曼编码对一篇英文进行压缩时,e极有可能用一个位(bit)来表示,而z则可能花去25个位(不是26)。用普通的表示方法时,每个英文字母均占用一个字节(byte),即8个位。二者相比,e使用了一般编码的1/8的长度,z则使用了3倍多。倘若我们能实现对于英文中各个字母出现概率的较准确的估算,就可以大幅度提高无损压缩的比例。

本文描述在网上能够找到的最简单,最快速的哈夫曼编码。本方法不使用任何扩展动态库,比如STL或者组件。只使用简单的C函数,比如:memset,memmove,qsort,malloc,realloc和memcpy。
因此,大家都会发现,理解甚至修改这个编码都是很容易的。

背景
哈夫曼压缩是个无损的压缩算法,一般用来压缩文本和程序文件。哈夫曼压缩属于可变代码长度算法一族。意思是个体符号(例如,文本文件中的字符)用一个特定长度的位序列替代。因此,在文件中出现频率高的符号,使用短的位序列,而那些很少出现的符号,则用较长的位序列。
编码使用
我用简单的C函数写这个编码是为了让它在任何地方使用都会比较方便。你可以将他们放到类中,或者直接使用这个函数。并且我使用了简单的格式,仅仅输入输出缓冲区,而不象其它文章中那样,输入输出文件。
bool CompressHuffman(BYTE *pSrc, int nSrcLen, BYTE *&pDes, int &nDesLen);
bool DecompressHuffman(BYTE *pSrc, int nSrcLen, BYTE *&pDes, int &nDesLen);
要点说明
速度
为了让它(huffman.cpp)快速运行,我花了很长时间。同时,我没有使用任何动态库,比如STL或者MFC。它压缩1M数据少于100ms(P3处理器,主频1G)。
压缩
压缩代码非常简单,首先用ASCII值初始化511个哈夫曼节点:
CHuffmanNode nodes[511];
for(int nCount = 0; nCount < 256; nCount++)
nodes[nCount].byAscii = nCount;
然后,计算在输入缓冲区数据中,每个ASCII码出现的频率:
for(nCount = 0; nCount < nSrcLen; nCount++)
nodes[pSrc[nCount]].nFrequency++;
然后,根据频率进行排序:
qsort(nodes, 256, sizeof(CHuffmanNode), frequencyCompare);
现在,构造哈夫曼树,获取每个ASCII码对应的位序列:
int nNodeCount = GetHuffmanTree(nodes);
构造哈夫曼树非常简单,将所有的节点放到一个队列中,用一个节点替换两个频率最低的节点,新节点的频率就是这两个节点的频率之和。这样,新节点就是两个被替换节点的父节点了。如此循环,直到队列中只剩一个节点(树根)。
// parent node
pNode = &nodes[nParentNode++];
// pop first child
pNode->pLeft = PopNode(pNodes, nBackNode--, false);
// pop second child
pNode->pRight = PopNode(pNodes, nBackNode--, true);
// adjust parent of the two poped nodes
pNode->pLeft->pParent = pNode->pRight->pParent = pNode;
// adjust parent frequency
pNode->nFrequency = pNode->pLeft->nFrequency + pNode->pRight->nFrequency;
这里我用了一个好的诀窍来避免使用任何队列组件。我先前就直到ASCII码只有256个,但我分配了511个(CHuffmanNode nodes[511]),前255个记录ASCII码,而用后255个记录哈夫曼树中的父节点。并且在构造树的时候只使用一个指针数组(ChuffmanNode *pNodes[256])来指向这些节点。同样使用两个变量来操作队列索引(int nParentNode = nNodeCount;nBackNode = nNodeCount –1)。
接着,压缩的最后一步是将每个ASCII编码写入输出缓冲区中:
int nDesIndex = 0;
// loop to write codes
for(nCount = 0; nCount < nSrcLen; nCount++)
{
*(DWORD*)(pDesPtr+(nDesIndex>>3)) |=
nodes[pSrc[nCount]].dwCode << (nDesIndex&7);
nDesIndex += nodes[pSrc[nCount]].nCodeLength;
}
(nDesIndex>>3): >>3 以8位为界限右移后到达右边字节的前面
(nDesIndex&7): &7 得到最高位.
注意:在压缩缓冲区中,我们必须保存哈夫曼树的节点以及位序列,这样我们才能在解压缩时重新构造哈夫曼树(只需保存ASCII值和对应的位序列)。
解压缩
解压缩比构造哈夫曼树要简单的多,将输入缓冲区中的每个编码用对应的ASCII码逐个替换就可以了。只要记住,这里的输入缓冲区是一个包含每个ASCII值的编码的位流。因此,为了用ASCII值替换编码,我们必须用位流搜索哈夫曼树,直到发现一个叶节点,然后将它的ASCII值添加到输出缓冲区中:
int nDesIndex = 0;
DWORD nCode;
while(nDesIndex < nDesLen)
{
nCode = (*(DWORD*)(pSrc+(nSrcIndex>>3)))>>(nSrcIndex&7);
pNode = pRoot;
while(pNode->pLeft)
{
pNode = (nCode&1) ? pNode->pRight : pNode->pLeft;
nCode >>= 1;
nSrcIndex++;
}
pDes[nDesIndex++] = pNode->byAscii;
}

android黑科技,图片终极压缩

一、支持自定义配置、不失真和批量处理

二、图片上传为什么要压缩
1、图片服务器空间限制,磁盘昂贵
2、网络不稳定,大文件需要断点续传
3、尽可能避免安卓OOM异常
4、后台约定的规则<200KB
5、需要上传原图的应用有医院临床项目、金融银行

三、图片压缩流程
1、递归每张图片
2、设置图片格式 Bitmap.CompressFormat.JPG
png, jpg,webp
3、质量压缩bitmap.compress(format,quality,baos)
由于png是无损压缩,所以设置quality无效(不适合作为缩略图)
采样率压缩BitmapFactory.Options.inSampleSize
缩小图片分辨率,减少所占用磁盘空间和内存大小
缩放压缩canvas.drawBitmap(bitmap, null,rectF,null)
减少图片的像素,降低所占用磁盘空间大小和内存大小,可用于缓存缩略图
JNI调用JPEG库
Android的图片引擎使用的是阉割版的skia引擎,去掉了图片压缩中的哈夫曼算法
4、像素修复
5、返回压缩
6、完成压缩

demo: https://github.com/ApeCold/Learn_Compress_Sample

参考:
Luban框架 https://github.com/Curzibn/Luban
缺点
1、当没有设定压缩路径时,抛异常无闪退
2、源码中,压缩比率固定值60,无法修改
3、压缩配置,参数不太适应真实项目需求
4、不能指定压缩大小,比如100KB以内
https://github.com/zettsu/Compressor

Ⅳ 图片压缩的原理

首先说明 jpeg图片:
JPEG是joint Photographic Experts Group(联合图像专家组)的缩写,文件后辍名为".jpg"或".jpeg",是最常用的图像文件格式,由一个软件开发联合会组织制定,是一种有损压缩格式,能够将图像压缩在很小的储存空间,图像中重复或不重要的资料会被丢失,因此容易造成图像数据的损伤。尤其是使用过高的压缩比例,将使最终解压缩后恢复的图像质量明显降低,如果追求高品质图像,不宜采用过高压缩比例。但是JPEG压缩技术十分先进,它用有损压缩方式去除冗余的图像数据,在获得极高的压缩率的同时能展现十分丰富生动的图像,换句话说,就是可以用最少的磁盘空间得到较好的图像品质。而且 JPEG是一种很灵活的格式,具有调节图像质量的功能,允许用不同的压缩比例对文件进行压缩,支持多种压缩级别,压缩比率通常在10:1到40:1之间,压缩比越大,品质就越低;相反地,压缩比越小,品质就越好。比如可以把1.37Mb的BMP位图文件压缩至20.3KB。当然也可以在图像质量和文件尺寸之间找到平衡点。JPEG格式压缩的主要是高频信息,对色彩的信息保留较好,适合应用于互联网,可减少图像的传输时间,可以支持24bit真彩色,也普遍应用于需要连续色调的图像。
JPEG格式是目前网络上最流行的图像格式,是可以把文件压缩到最小的格式,在 Photoshop软件中以JPEG格式储存时,提供11级压缩级别,以0—10级表示。其中0级压缩比最高,图像品质最差。即使采用细节几乎无损的10 级质量保存时,压缩比也可达 5:1。以BMP格式保存时得到4.28MB图像文件,在采用JPG格式保存时,其文件仅为178KB,压缩比达到24:1。经过多次比较,采用第8级压缩为存储空间与图像质量兼得的最佳比例。
JPEG格式的应用非常广泛,特别是在网络和光盘读物上,都能找到它的身影。目前各类浏览器均支持JPEG这种图像格式,因为JPEG格式的文件尺寸较小,下载速度快。
JPEG2000作为JPEG的升级版,其压缩率比JPEG高约30%左右,同时支持有损和无损压缩。JPEG2000格式有一个极其重要的特征在于它能实现渐进传输,即先传输图像的轮廓,然后逐步传输数据,不断提高图像质量,让图像由朦胧到清晰显示。此外,JPEG2000还支持所谓的"感兴趣区域" 特性,可以任意指定影像上感兴趣区域的压缩质量,还可以选择指定的部分先解压缩。
JPEG2000和JPEG相比优势明显,且向下兼容,因此可取代传统的JPEG格式。JPEG2000即可应用于传统的JPEG市场,如扫描仪、数码相机等,又可应用于新兴领域,如网路传输、无线通讯等等。
优点:
摄影作品或写实作品支持高级压缩。
利用可变的压缩比可以控制文件大小。
支持交错(对于渐近式 JPEG 文件)。
JPEG 广泛支持 Internet 标准。
缺点:
有损耗压缩会使原始图片数据质量下降。
当您编辑和重新保存 JPEG 文件时,JPEG 会混合原始图片数据的质量下降。这种下降是累积性的。
JPEG 不适用于所含颜色很少、具有大块颜色相近的区域或亮度差异十分明显的较简单的图片。
你看不出改变 不等于没有改变,人的视力范围里有些色彩的区别是无法分辨的,而把这些图片信息去掉,你看起来没区别,但图片大小已经被压缩了

Ⅳ 算法解析:哈夫曼(huffman)压缩算法

本篇将介绍 哈夫曼压缩算法(Huffman compression)

众所周知,计算机存储数据时,实际上存储的是一堆0和1(二进制)。

如果我们存储一段字符:ABRACADABRA!

那么计算机会把它们逐一翻译成二进制,如A:01000001;B: 01000010; !: 00001010.

每个字符占8个bits, 这一整段字符则至少占12*8=96 bits。

但如果我们用一些特殊的值来代表这些字符,如:

图中,0代表A; 1111代表B;等等。此时,存储这段字符只需30bits,比96bits小多了,达到了压缩的目的。

我们需要这么一个表格来把原数据翻译成特别的、占空间较少的数据。同时,我们也可以用这个表格,把特别的数据还原成原数据。

首先,为了避免翻译歧义,这个表格需满足一个条件: 任何一个字符用的值都不能是其它字符的前缀

我们举个反例:A: 0; B: 01;这里,A的值是B的值的前缀。如果压缩后的数据为01xxxxxx,x为0或者1,那么这个数据应该翻译成A1xxxxxx, 还是Bxxxxxxx?这样就会造成歧义。

然后,不同的表格会有不同的压缩效果,如:

这个表格的压缩效果更好。

那么我们如何找到 最好的表格 呢?这个我们稍后再讲。

为了方便阅读,这个表格是可以写成一棵树的:

这棵树的节点左边是0,右边是1。任何含有字符的节点都没有非空子节点。(即上文提及的前缀问题。)

这棵树是在压缩的过程中建成的,这个表格是在树形成后建成的。用这个表格,我们可以很简单地把一段字符变成压缩后的数据,如:

原数据:ABRACADABRA!

表格如上图。

令压缩后的数据为S;

第一个字符是A,根据表格,A:11,故S=11;

第二个字符是B,根据表格,B:00,故S=1100;

第三个字符是R,根据表格,R:011,故S=1100011;

如此类推,读完所有字符为止。

压缩搞定了,那解压呢?很简单,跟着这棵树读就行了:

压缩后的数据S=11000111101011100110001111101

记住,读到1时,往右走,读到0时,往左走。

令解压后的字符串为D;

从根节点出发,第一个数是1,往右走:

第二个数是1,往右走:

读到有字符的节点,返回此字符,加到字符串D里。D:A;

返回根节点,继续读。

第三个数是0,往左走:

第四个数是0,往左走:

读到有字符的节点,返回此字符,加到字符串D里。D:AB;

返回根节点,继续读。

第五个数是0,往左走:

第六个数是1,往右走:

第七个数是1,往右走:

读到有字符的节点,返回此字符,加到字符串D里。D:ABR;

返回根节点,继续读。

如此类推,直到读完所有压缩后的数据S为止。

压缩与解压都搞定了之后 我们需要先把原数据读一遍,并把每个字符出现的次数记录下来。如:

ABRACADABRA!中,A出现了5次;B出现了2次;C出现了1次;D出现了1次;R出现了2次;!出现了1次。

理论上,出现频率越高的字符,我们给它一个占用空间越小的值,这样,我们就可以有最佳的压缩率

由于哈夫曼压缩算法这块涉及内容较多 ,文章篇幅很长;全文全方面讲解了Compose布局的各方面知识。更多Android前言技术进阶,我自荐一套《 完整的Android的资料,以及一些视频课讲解 现在私信发送“进阶”或者“笔记”即可免费获取



最后我想说:

对于程序员来说,要学习的知识内容、技术有太多太多,要想不被环境淘汰就只有不断提升自己,从来都是我们去适应环境,而不是环境来适应我们

技术是无止境的,你需要对自己提交的每一行代码、使用的每一个工具负责,不断挖掘其底层原理,才能使自己的技术升华到更高的层面

Android 架构师之路还很漫长,与君共勉

Ⅵ 如何用哈夫曼编码对图像进行压缩

% 演示图象的哈夫曼编解码过程
% chenyong 2009.04.20

clear all;
close all;
clc;
Dimens = 256; % 矩阵维数,假设矩阵为方阵即256*256
src_size = Dimens^2; % 矩阵元素的个数
gray_level = 9; % 灰度级

src = randn(Dimens); %产生模拟图像矩阵,满足正态分布,零均值,方差为1
%src = randint(Dimens,Dimens,gray_level); % 产生随机图像矩阵,灰度值为0~63,满足均匀分布
src_one = reshape(src,1,src_size);
src_max = max(src_one);
src_min = min(src_one);
quan = linspace(src_min,src_max,gray_level); % 产生均匀量化区间
src_d = []; % 数字矩阵
for row = 1:Dimens % 逐点量化
for vol = 1:Dimens
diff = abs(src(row,vol)-quan);
[min_diff,min_index] = min(diff);
quan_gray = min_index -1;
src_d(row,vol) = quan_gray;
end
end

%将数字图像矩阵还原成模拟矩阵
src_a = [];
quan_space = quan(2)-quan(1);
for row = 1:Dimens
for vol = 1:Dimens
src_a(row,vol) = src_d(row,vol) * quan_space + src_min;
end
end

% prob数组保存图像中各灰度出现的概率
prob = [];
for src_value=0:(gray_level-1)
index = find(src_d==src_value);
i = src_value + 1;
prob(i) = length(index)/src_size;
end

% 画出直方图
% stem(0:gray_level-1,prob);
% xlabel('灰度值');
% ylabel('概率');
% title('灰度直方图');

% huffman编码
p = prob;
n=length(p);
q=p;
m=zeros(n-1,n);
for i=1:n-1
[q,l]=sort(q);
m(i,:)=[l(1:n-i+1),zeros(1,i-1)];
q=[q(1)+q(2),q(3:n),1];
end
bre=zeros(n-1,n);
bre(n-1,1)=0+j; %虚部表示当前的二进制数的位数,以下类似
bre(n-1,2)=1+j;
for time=1:n-2
loc_1 = find(real(m(n-time,:))==1);
prebit = bre(n-time,loc_1);
bre(n-time-1,1) = (real(prebit)*2 + 0) + j*(imag(prebit)+1);
bre(n-time-1,2) = (real(prebit)*2 + 1) + j*(imag(prebit)+1);

loc_not1 = find(real(m(n-time,:))>1);
bre(n-time-1,3:3+time-1) = bre(n-time,loc_not1);
end
[m1,index] = sort(m(1,:));
code = bre(1,index);
code_data = real(code);
code_bits = imag(code);
disp(['gray level',' ', 'huffman code']);
for i = 1:length(code)
disp([num2str(i-1),' ' ,num2str(dec2bin(code_data(i)))]);
disp([num2str(i-1),' ' ,num2str(dec2bin(code_data(i),code_bits(i)))]);
end
code_binary = dec2bin(code_data);

%逐点编码
out = [];
for row = 1:Dimens
for vol = 1:Dimens
now_gray = src_d(row,vol);
now_code = code_binary(now_gray+1,:);
now_bits = code_bits(now_gray+1);
now_code = now_code(end-now_bits+1:end);
out = [out, now_code];
end
end

%计算压缩比
real_bitnum = length(out);
bitnum_no_huffman = src_size*nextpow2(gray_level);
comp_ratio =bitnum_no_huffman/real_bitnum;
Lavg = real_bitnum/src_size;
Hshannon = (-1)*prob*(log2(prob))';
disp(['Lavg = ',num2str(Lavg)]);
disp(['normal bit num = ',num2str(nextpow2(gray_level))]);
disp(['comp_ratio = ',num2str(comp_ratio)]);
disp(['Hshannon = ',num2str(Hshannon)]);

Ⅶ libjpeg-turbo 图片压缩

android7.0之前,Bitmap.compress不支持哈夫曼压缩算法,压缩效率不高,因此引入libTurboJpeg库来改善压缩效率。
安卓底层使用Skia作为它的图片处理引擎,通过对libjpeg进行封装,来进行压缩图片。然而在libjpeg进行压缩图片时,有一个参数,叫optimize_coding,默认为FALSE。关于这个参数,官方的解释是,如果设置为TRUE,在压缩过程中,会计算哈夫曼表,这会显着消耗空间和时间。

然而这是对于十几年前的设备而言的,现在的设备来做这个计算完全没有压力。因此,只有在安卓7.0之后,才支持了哈夫曼算法。

开发时,把Java层的Bitmap传递到native层,然后使用 AndroidBitmap API 取出图像所有的argb数据,接着可以舍弃a通道信息,只保留rgb信息到一个新的uint_8数组中,将这个数组作为参数传入jpeg-turbo库中,开启哈夫曼编码,就可以保存到一个新的路径中。
参考链接: https://www.jianshu.com/p/32ff62bc33d5?from=timeline

我们来看看2,6,8,9,3权值节点构成哈夫曼树的过程。

初始时候各个节点独立,先将其排序(这里使用优先队列),然后选两个最小节点(抛出)生成一个新的节点,再将其加入优先队列中,此次操作完成后优先队列中有5,6,8,9节点

重复上面操作,这次结束 队列中有11,8,9节点(排序后8,9,11)

如果队列为空,那么返回节点,并且这个节点为整个哈夫曼树根节点root。

否则继续加入队列进行排序。重复上述操作,直到队列为空。

先统计字符出现的次数,然后将这个次数当成权值按照上面介绍的方法构造一棵哈夫曼树,然后树的根不存,往左为0往右为1每个叶子节点得到的二进制数字就是它的编码,这样频率高的字符在上面更短在整个二进制存储中也更节省空间。

Ⅷ 利用哈夫曼编码进行压缩压缩率一般达到多少

哈夫曼编码进行压缩的压缩率是根据平均码长来计算的,压缩率比较低。

例如:用三位二进行数进行的等长编码平均长度为3,而根据哈夫曼树编码的平均码长为:

4*0.07+2*0.19+5*0.02+4*0.06+2*0.32+5*0.03+2*0.21+4*0.10=2.61

2.61/3=0.87=87%

其平均码长是等长码的87%,所以平均压缩率为13%。

哈夫曼编码,又称霍夫曼编码,是一种编码方式,哈夫曼编码是可变字长编码(VLC)的一种。

Huffman于1952年提出一种编码方法,该方法完全依据字符出现概率来构造异字头的平均长度最短的码字,有时称之为最佳编码,一般就叫做Huffman编码(有时也称为霍夫曼编码)。

压缩率,描述压缩文件的效果名,是文件压缩后的大小与压缩前的大小之比,例如:把100m的文件压缩后是90m,压缩率为90/100*100%=90%,压缩率一般是越小越好,但是压得越小,解压时间越长。

(8)哈夫曼图片压缩扩展阅读

哈夫曼编码的具体方法:先按出现的概率大小排队,把两个最小的概率相加,作为新的概率 和剩余的概率重新排队,再把最小的两个概率相加,再重新排队,直到最后变成1。

每次相 加时都将“0”和“1”赋与相加的两个概率,读出时由该符号开始一直走到最后的“1”, 将路线上所遇到的“0”和“1”按最低位到最高位的顺序排好,就是该符号的哈夫曼编码。

Ⅸ 如何写压缩软件,运用哈夫曼算法实现

到文件压缩大家很容易想到的就是rar,zip等我们常见的压缩格式。然而,还有一种就是大家在学习数据结构最常见到的哈夫曼树的数据结构,以前还不知道他又什么用,其实他最大的用途就是用来做压缩,也是一些rar,zip压缩的祖先,称为哈弗曼压缩(什么你不知道谁是哈弗曼,也不知道哈弗曼压缩,不急等下介绍)。

随着网络与多媒体技术的兴起,人们需要存储和传输的数据越来越多,数据量越来越大,以前带宽有限的传输网络和容量有限的存储介质难以满足用户的需求。

特别是声音、图像和视频等媒体在人们的日常生活和工作中的地位日益突出,这个问题越发显得严重和迫切。如今,数据压缩技术早已是多媒体领域中的关键技术之一。

一、什么是哈弗曼压缩

Huffman(哈夫曼)算法在上世纪五十年代初提出来了,它是一种无损压缩方法,在压缩过程中不会丢失信息熵,而且可以证明Huffman算法在无损压缩算法中是最优的。Huffman原理简单,实现起来也不困难,在现在的主流压缩软件得到了广泛的应用。对应用程序、重要资料等绝对不允许信息丢失的压缩场合,Huffman算法是非常好的选择。

二、怎么实现哈弗曼压缩

哈夫曼压缩是个无损的压缩算法,一般用来压缩文本和程序文件。哈夫曼压缩属于可变代码长度算法一族。意思是个体符号(例如,文本文件中的字符)用一个特定长度的位序列替代。因此,在文件中出现频率高的符号,使用短的位序列,而那些很少出现的符号,则用较长的位序列。

故我们得了解几个概念:

1、二叉树:在计算机科学中,二叉树是每个结点最多有两个子树的有序树。通常子树的根被称作“左子树”(left subtree)和“右子树”(right subtree)。2、哈夫曼编码(Huffman Coding):是一种编码方式,哈夫曼编码是可变字长编码(VLC)的一种。uffman于1952年提出一种编码方法,该方法完全依据字符出现概率来构造异字头的平均长 度最短的码字,有时称之为最佳编码,一般就叫作Huffman编码。三、哈夫曼编码生成步骤:

①扫描要压缩的文件,对字符出现的频率进行计算。

②把字符按出现的频率进行排序,组成一个队列。

③把出现频率最低(权值)的两个字符作为叶子节点,它们的权值之和为根节点组成一棵树。

④把上面叶子节点的两个字符从队列中移除,并把它们组成的根节点加入到队列。

⑤把队列重新进行排序。重复步骤③④⑤直到队列中只有一个节点为止。

⑥把这棵树上的根节点定义为0(可自行定义0或1)左边为0,右边为1。这样就可以得到每个叶子节点的哈夫曼编码了。

既如 (a)、(b)、(c)、(d)几个图,就可以将离散型的数据转化为树型的了。

如果假设树的左边用0表示右边用1表示,则每一个数可以用一个01串表示出来。

则可以得到对应的编码如下:
1-->110
2-->111
3-->10
4-->0
每一个01串,既为每一个数字的哈弗曼编码。
为什么能压缩:
压缩的时候当我们遇到了文本中的1、2、3、4几个字符的时候,我们不用原来的存储,而是转化为用它们的01串来存储不久是能减小了空间占用了吗。(什么01串不是比原来的字符还多了吗?怎么减少?)大家应该知道的,计算机中我们存储一个int型数据的时候一般式占用了2^32-1个01位,因为计算机中所有的数据都是最后转化为二进制位去存储的。所以,想想我们的编码不就是只含有0和1嘛,因此我们就直接将编码按照计算机的存储规则用位的方法写入进去就能实现压缩了。
比如:
1这个数字,用整数写进计算机硬盘去存储,占用了2^32-1个二进制位
而如果用它的哈弗曼编码去存储,只有110三个二进制位。
效果显而易见。

Ⅹ 哈夫曼压缩算法的内容是什么

注:哈夫曼和lzss算法不是同一种算法,先用哈夫曼再用lzss算法压缩后会发现经哈夫曼压缩后再用lzss压缩文件会变大,具体原因不明
lzss原理:
把编码位置置于输入数据流的开始位置。
在前向缓冲器中查找窗口中最长的匹配串

pointer
:=匹配串指针。

length
:=匹配串长度。
判断匹配串长度length是否大于等于最小匹配串长度(min_length)

如果“是”:输出指针,然后把编码位置向前移动length个字符。
如果“否”:输出前向缓冲存储器中的第1个字符,然后把编码位置向前移动一个字符。
如果前向缓冲器不是空的,就返回到步骤2。
例:编码字符串如表03-05-3所示,编码过程如表03-05-4所示。现说明如下:
“步骤”栏表示编码步骤。
“位置”栏表示编码位置,输入数据流中的第1个字符为编码位置1。
“匹配”栏表示窗口中找到的最长的匹配串。
“字符”栏表示匹配之后在前向缓冲存储器中的第1个字符。
“输出”栏的输出为:

如果匹配串本身的长度length
>=
min_length,输出指向匹配串的指针,格式为(back_chars,
chars_length)。该指针告诉译码器“在这个窗口中向后退back_chars个字符然后拷贝chars_length个字符到输出”。

如果匹配串本身的长度length
>=
min_length,则输出真实的匹配串。
表:输入数据流
位置
1234567891011
字符
aabbcbbaabc
表:编码过程(min_length
=
2)
步骤位置匹配串输出
11--a
22aa
33--
b
44bb
55--c
66b
b(3,2)
78
a
a
b(7,3)
811cc

阅读全文

与哈夫曼图片压缩相关的资料

热点内容
asp用户注册源码 浏览:48
什么是照片压缩文件 浏览:392
java调用js代码 浏览:979
昆山市民app怎么修改身份信息 浏览:779
php登陆次数 浏览:744
python字符转成数字 浏览:822
海川用的是什么服务器 浏览:376
口才是练出来的pdf 浏览:458
云服务器哪个公司性价比高 浏览:517
源码论坛打包 浏览:558
php怎么做成word 浏览:692
python批量生成密钥 浏览:492
程序员要不要考社区人员 浏览:150
app的钱怎么充q币 浏览:813
android银行卡识别 浏览:755
怎么在app投放广告 浏览:11
手机文件管理怎么看app名称 浏览:192
程序员学数学哪本书最全 浏览:788
macd实战选股公式源码 浏览:644
加密芯片的计算方法 浏览:191