- 浏览: 205090 次
- 性别:
- 来自: 长沙
最新评论
-
螺旋懒虫:
原本是想自己画点阵的,一来画的不标准,也不好解析(用excel ...
超级详细解析——字模 -
螺旋懒虫:
这个程序解决了我怎么加载点阵字库文件的问题,和怎么去拿到汉字对 ...
超级详细解析——字模 -
慕容墨风:
你好,我用你的测试程序发现数字提取不了
超级详细解析——字模 -
文之若素:
求代码,我最近在学这个,公司需要,呜呜呜,159374403 ...
初学EXTJS做的系统界面 -
csrhlu:
为什么我压缩之后文件还变大了呢? 而且解压eclipse下边会 ...
自己动手写压缩软件,超详细解释(哈夫曼实现)
Lzw 针对大量的子串多次重复出现的压缩
之前用了一个哈弗曼算法给大家实现了文件的压缩处理,其实上,文件压缩的原理很简单,无非就是把重复出现的元素,用一个特定的方式转化为跟少量的信息来存储。今天我所给大家分享的就是一个更为引用广泛的压缩算法lzw压缩算法。
一、lzw的介绍
LZW压缩算法是一种新颖的压缩方法,由Lemple-Ziv-Welch 三人共同创造,用他们的名字命名。它采用了一种先进的串表压缩,将每个第一次出现的串放在一个串表中,用一个数字来表示串,压缩文件只存贮数字,则不存贮串,从而使图象文件的压缩效率得到较大的提高。奇妙的是,不管是在压缩还是在解压缩的过程中都能正确的建立这个串表,压缩或解压缩完成后,这个串表又被丢弃。
简单的说明一下:
Ababcabab这个字符串,开起来9个字符组成的,但是会发现一点就是ab这个字符组合比较的多。如果我们用一个数字,也就是7来表示ab的话,则字符串就变为了77c77,这样一来字符串的字符个数就变为了5个,如果大家仔细些会发现,如果我们用一个数字8来表示abab,则原来的字符串就变为了8c8只有3个字符了,是不是很神奇哈。
从这个例子我们就可以看出LZW算法的适用范围是原始数据串最好是有大量的子串多次重复出现,重复的越多,压缩效果越好。反之则越差,可能真的不减反增了。
比如:
一个如此重复的文件:
压缩后效果就非常的显著: 文件大小变为原来的1/30 具体思想: 比如我们大家所熟知的ASCII码,这个码表是与我们常见的字符是一一对应的,比如我们说‘a’,我们也可以写成97,这两者就是等价的。其实上这就是一个码表。所以人们就想到,我们可不可以用以一个码表示一个或者多个的字符,比如8表示ab这两字符,我们就能将abcab这种的字符串缩小为8c8了。 但是我们知道字节只有0~255,如果我们要扩展的话就必须增加自己的定义。既,我假设我用增加了256~65534这么一段表示新的码表。 具体步骤: ①打开一个待压缩文件与存放压缩后的文件 ②读入一个字节作为后缀,判断这个词字典中是否存在,存在则直接输出,不存在则加入字典中。 ③如果超过了最大的长度则,将当前码表写出到文件中,清空,再次读入 ④最后,将没有写完的信息,和码表都输出,压缩就完成了 举一个例子说明: 先说两个概念 前缀prefix:一个词组的前面一个字符 ,比如 ab,前缀为a,8f前缀为8 后最suffix:反之,为后一个字符,比如 ab,后缀为b,8f后缀为f 有了前缀后缀,我们就能清楚的表示出来一个词了。 同样,我们还来做一个字符串 ababbacb 8个字符 第几步 前缀 后缀 词 存在对应码 输出 码 1 a (,a) 2 a b (a,b) no a 256 3 b a (b,a) no b 257 4 a b (a,b) yes 5 256 b (256,b) no 256 258 6 b a (b,a) yes 7 257 c (257,c) no 257 259 8 c b (c,b) no c 260
大小为:
把输出来的和最后一个后缀连在一起则是:
a,b,256,257,c,b
6个字符,那么就达到了压缩的目的。
对应生成的码表则是:
256 |
257 |
258 |
259 |
260 |
(a,b) |
(b,a) |
(256,b) |
(257,c) |
(c,b) |
解压缩就很简单了,将输出字符串按照码表对应转化回来就实现了。
即
a,b,256(ab),257(ba),c,b
即 ababbacb
压缩成功。
当然我们不能一直无穷之境的增加码表的长度,再说内存也容不下这么长的码表。正如我之前所说的,我用了0~65534保存字节所对应的编码,0~255是系统字节的长度,256~65534是我自己定义的。如果超过了65534的话,我们这必须再次编码。即将原来所对应的编码输出,将256~65534这一段清空,再次编码就可以了。
为了记录我们是在哪里清空的,所有又在文件中写一个字符,表示 “清除”,我的程序中用的是65535表示。
详细代码设计
压缩过程
①打开一个待压缩文件与存放压缩后的文件
②读入一个字节作为后缀,判断这个词字典中是否存在,存在则直接输出,不存在则加入字典中。 //打开被压缩文件
java.io.FileInputStream fis = new java.io.FileInputStream(path);
//压缩文件输出流
java.io.FileOutputStream fos = new java.io.FileOutputStream(path+".stzip");
java.io.DataOutputStream dos = new java.io.DataOutputStream(fos);
③如果超过了最大的长度则,将当前码表写出到文件中,清空,再次读入prefix=fis.read();//读入一个字节
while(fis.available()>0){
suffix=fis.read();//读入一个后缀
index=lz.getIndex(prefix, suffix);//得到对应的下标
if(index!=-1){//存在元素在表里面
prefix=index;//前序变为标号
}else{//在表里不存在
// System.out.println("输出了~"+prefix);
dos.writeChar(prefix);//输出前缀
lz.add(prefix,suffix);//加入到表中
prefix=suffix;//前缀变为后缀
}
}
if(lz.length==lzw.Max_Length){//超过最大长度则,重置 dos.writeChar(65535);//写出一个65535作为重置的标示 与码表的打印 //写出码表 // dos.writeInt(lz.length);//码表长度 System.out.println("写出长度~"+lz.length); for(int i=256;i<lz.length;i++){ dos.writeChar(lz.node[i].prefix);//前缀写出 dos.writeChar(lz.node[i].suffix);//后缀写出 } lz = new lzw();//清空原来信息 }
④最后,将没有写完的信息,和码表都输出,压缩就完成了
dos.writeChar(prefix);//输出最后一个没有配对的 //输出最后的的码表 // System.out.println("写出标记~"+65535); dos.writeChar(65535);//写出一个-1作为重置的标示 与码表的打印 //写出码表 dos.writeInt(lz.length-256);//码表长度 //System.out.println("写出长度~"+(lz.length-256)); for(int i=256;i<lz.length;i++){ //System.out.println("写出前后缀~"+lz.node[i].prefix+","+lz.node[i].suffix); dos.writeChar(lz.node[i].prefix);//前缀写出 dos.writeChar(lz.node[i].suffix);//后缀写出 }
解压缩过程:
①读入码表之前的压缩信息
char data; int current=0; char []codeData = new char[65536]; lzw lz = new lzw();//自定义码表 data=dis.readChar(); //System.out.println("读取字符~"+data); while(data!=65535){//把码表钱的东西读取出来 // System.out.println("开打文件中有的内容"+current+"是"+data); codeData[current]=data; current++;//当前位置增加 data=dis.readChar(); }
②读入对应长度的码表
int length = dis.readInt();//得到码表的长度 //System.out.println("独到的长度"+length); for(int i=0;i<length;i++){//读入码表 int prefix = dis.readChar(); int suffix = dis.readChar(); //System.out.println("第"+i+"个的数据"+prefix+","+suffix); lz.add(prefix, suffix); }
③翻译编码,写出源文件
//解压缩、写出该部分的源文件 for(int i=0;i<current;i++){ //System.out.println("传进来的数据是~"+codeData[i]); lz.writeIt(dos, codeData[i]); public void writeIt(java.io.DataOutputStream dos,int index){ // System.out.println("进来的index是"+index); if(index>255){//是生成的码则需要转化为byte输出 writeIt(dos,node[index].prefix); writeIt(dos,node[index].suffix); }else{ try { // System.out.println("解压输出了~"+index); //char data=(char) index; dos.write((char)index); //dos.writeChar(data); } catch (IOException e) { e.printStackTrace(); } } }
比较,lzw和哈弗曼做比较,lzw的代码更为简便,实现更为简单,效率也比哈弗曼高。但是LZW得算法比较难以理解。
评论
是的,忘记说了,lzw的主要应用就是GIF
发表评论
-
《动感地下城》,让宅男变猛男
2011-10-03 11:11 1598动感地下城 写在之前: 好久都没有发表文章了, ... -
RGP游戏的非主流应用——虚拟地图
2011-06-30 01:02 6113RGP游戏的非主流应用——虚拟地图 写在之前: 本 ... -
一个项目完整制作过程的分享
2011-05-22 14:23 8215St书店管理系统 写在文章之前: 本项 ... -
一个项目完整制作过程的分享
2011-05-22 14:18 0St书店管理系统 写在文章之前: 本项 ... -
eclipse下的1245个图标
2011-05-19 17:23 2154eclipse下的1245个图标 大家随便拿写 ... -
超级详细解析——字模
2011-05-17 21:09 6721超级详细解析——字模 一、简介 汉字库: 即 ... -
JavaSE 的MV模式(国际化)
2011-05-14 12:13 2770JavaSE 的 MV 模式 ... -
分享一个绿色版本的 JAR TO EXE工具(附上一个视频教程)
2011-03-15 14:05 1563如题,使用灰常简单 附上一个视频教程: -
偶然玩分形 java测试
2011-03-09 13:54 2598分形世界 我从拉丁文形容词fractus(分裂的)造出了fr ... -
Oracle, SQL Server, My SQL数据分页查询语句汇总
2011-03-05 23:16 2024之前一直在学习SQL Server,然而其的分 ... -
小议MVC模式开发
2011-02-27 22:08 1286做web项目是所经常提到的mvc模式。 MVC是三个 ... -
菜鸟 利用VE、截图 快速打造仿QQ绚丽界面
2011-02-12 02:52 2952自绘菜鸟 利用VE、截图 快速打造仿QQ绚丽界面 ... -
JAVA的几个重要概念小总结
2011-01-17 12:20 1407JAVA的几个重要概念小总结 方法声明: 写一个方 ... -
几个文字编码小总结
2011-01-17 12:03 1202ASCII 我们入门学习是最 ... -
超详细解释常用网络命令
2011-01-15 12:10 1580常用网络命令 PING请求 Ping www.google ... -
达通杯 赛后感想
2010-12-23 13:09 3586比赛结束两三天了今天才抽出了时间写写心得。 其实想想自己 ... -
自己动手写压缩软件,超详细解释(哈夫曼实现)
2010-12-04 10:58 19705说到文件压缩大家很容 ... -
JAVA BMP解码 超详细解释
2010-11-21 23:02 13396首先,对于BMP 格式的图片大家都不感觉到陌生吧。 ... -
Java 挂链 Hash表 手动实现
2010-11-19 13:08 2182前些天一直在纠结的 ... -
五子棋 图片版
2010-11-16 12:45 5526近来发现自绘的东西怎么都比不了自己PS加载图片所作的界面好看。 ...
相关推荐
- **高效性**:对于包含重复模式的数据,LZW能实现较高的压缩比。 - **无损压缩**:LZW是无损压缩算法,解压缩后的数据与原始数据完全一致。 5. **应用场景**: - LZW广泛应用于文件压缩,如GIF图像格式就是使用...
LZW压缩是一种完全可逆的压缩方式,所有原始信息都被保留,其符号表在压缩和解压缩过程中完全自动生成,对于平滑和无噪声的简单图像,可以达到非常高的压缩比。 ### LZW压缩技术的特点 LZW压缩技术具有以下几个...
LZW算法通常不直接设置压缩比,而是通过调整字典大小来影响压缩效果。字典越大,压缩率可能越低,但解压缩速度更快;反之,字典越小,压缩率越高,但解压缩可能需要更多时间。在VB6程序中,可能通过参数控制字典的...
该算法的主要特点在于其高效性和通用性,在许多应用场合下都能实现较好的压缩比,尤其是在文本和图像数据的压缩方面表现突出。LZW算法是基于字典的压缩方法,通过构建一个动态字典来存储出现过的字符串,从而实现对...
随着过程的推进,字典会不断增大,压缩比也随之提高。在C语言中实现LZW算法,需要处理字典管理、编码与解码过程,以及考虑如何高效地存储和检索字典条目。 Huffman编码是一种基于字符频率的变长编码方法,由David A...
7. **应用与限制**:LZW算法在文件压缩软件如早期的GIF图像格式中得到广泛应用。然而,由于专利问题,它不再广泛用于现代压缩标准,如PNG和JPEG。此外,LZW对无损压缩和有序数据表现良好,但对随机数据的压缩效果不...
4. **动态阈值调整**:根据输入数据的特性,可以动态调整压缩阈值,以适应不同数据源的压缩需求,比如对于重复率高的数据,可以降低阈值,提高压缩比。 5. **并行处理**:MATLAB环境支持多线程计算,改进的LZW可能...
1. 避免了LZW算法会增大文件大小这个缺陷 2. 提供存储的压缩方法 3. 提升了压缩比 4. 提升了程序的执行速度 程序使用ANSI C语言编写,可在多平台下编译。压缩包内附编译好的程序、源代码和说明文档。谢谢大家的支持...
在实际应用中,LZW算法由于其效率和压缩比而被广泛采用,但也有版权问题,因为它曾是Compress软件的一部分,这导致在某些场合(如GIF图像格式)中受到了限制。不过,LZW的变种和类似算法依然在很多领域中得到应用,...
3. **高效性**:尽管LZW算法在压缩过程中需要维护和更新字典,但其时间复杂度相对较低,且能实现较高的压缩比。 4. **可变长度编码**:LZW使用可变长度编码,较短的字符串编码较短,常见的模式编码更短,从而节省...
基于Xilinx FPGA实现LZW压缩算法,经过仿真验证与硬件验证,结果表明该算法的FPGA实现能获得20%左右的压缩比,工作速率12.72MB/s。FPGA资源利用率非常低,完全满足系统实时处理的需求。 本文对基于FPGA实现压缩算法...
LZW算法通过动态字典和自适应编码机制实现了高效的数据压缩和解压。它特别适用于需要快速处理大量数据的应用场景,如文件压缩、网络传输等领域。通过调整关键参数和优化数据结构,可以进一步提升LZW算法的性能和压缩...
本文将详细介绍LZW算法的工作原理及其在数字音频和图像处理中的应用。 ### 1. LZW算法基础 LZW的核心思想是通过构建一个动态的编码表来查找重复模式,并用更短的编码代替这些模式,从而实现数据的压缩。这个过程...
对于简单图像和平滑且噪声小的信号源具有较高的压缩比,并且有较高的压缩和解压缩速度。 LZW压缩技术把数据流中复杂的数据用简单的代码来表示,并把代码和数据的对应关系建立一个转换表,又叫“字符串表”。 转换...
LZW算法和滑动平均滤波算法的理论基础被介绍,并且详细说明了如何使用单片FPGA实现这两种算法。测试结果表明,该方案能有效滤除数据中的高频噪声,并且在压缩比和处理速度上表现良好,具有一定的实用价值。 LZW压缩...
LZW算法是由Abraham Lempel、Jacob Ziv和Willis Welch共同开发的一种字典编码方法,它通过构建动态字典来实现数据的压缩。在压缩过程中,LZW算法首先将输入的数据流分割成一系列的字符串,然后查找这些字符串是否...
有损压缩在数据重构过程中允许存在一定的误差,从而获得较高的压缩比;无损压缩则要求重构后的数据与原始数据完全一致。LZW算法属于无损压缩的一种,通过构建一个字符串表(或称为字典)来存储首次出现的字符串,...