Chinaunix首页 | 论坛 | 博客
  • 博客访问: 5520508
  • 博文数量: 763
  • 博客积分: 12108
  • 博客等级: 上将
  • 技术积分: 15717
  • 用 户 组: 普通用户
  • 注册时间: 2007-09-28 21:21
个人简介

业精于勤,荒于嬉

文章分类

全部博文(763)

文章存档

2018年(6)

2017年(15)

2016年(2)

2015年(31)

2014年(14)

2013年(87)

2012年(75)

2011年(94)

2010年(190)

2009年(38)

2008年(183)

2007年(28)

分类: C/C++

2010-03-01 20:30:38

上面我们已经对PNG的存储格式有了了解,因此,生成PNG图片只需要按照以上的数据块写入文件即可。

(由于IHDR、PLTE的结构都非常简单,因此,这里我们只是重点讲一讲IDAT的生成方法,IHDR和PLTE的数据内容都沿用以上的数据内容)
问题确实是这样的,我们知道,对于大多数的图形文件来说,我们都可以将实际的图像内容映射为一个二维的颜色数组,对于上面的PNG文件,由于它用的是16色的调色板(实际是13色),因此,对于图片的映射可以如下:

调色板对照图

(调色板对照图)
12  11  10  9  8  7  6  5 
11  10  9  8  7  6  5  4 
10  9  8  7  6  5  4  3 
9  8  7  6  5  4  3  2 
8  7  6  5  4  3  2  1 
7  6  5  4  3  2  1  0 
6  5  4  3  2  1  0  0 
5  4  3  2  1  0  0  0 

PNG Spec中指出,如果PNG文件不是采用隔行扫描方法存储的话,那么,数据是按照行(ScanLine)来存储的,为了区分第一行,PNG规定在每一行的前面加上0以示区分,因此,上面的图像映射应该如下:
0  12  11  10  9  8  7  6  5 
0  11  10  9  8  7  6  5  4 
0  10  9  8  7  6  5  4  3 
0  9  8  7  6  5  4  3  2 
0  8  7  6  5  4  3  2  1 
0  7  6  5  4  3  2  1  0 
0  6  5  4  3  2  1  0  0 
0  5  4  3  2  1  0  0  0 

另外,需要注意的是,由于PNG在存储图像时为了节省空间,因此每一行是按照位(Bit)来存储的,而并不是我们想象的字节(Byte),如果你没有忘记的话,我们的IHDR数据块中的色深就指明了这一点,所以,为了凑成PNG所需要的IDAT,我们的数据得改成如下:
0  203  169  135  101 
0  186  152  118  84 
0  169  135  101  67 
0  152  118  84  50 
0  135  101  67  33 
0  118  84  50  16 
0  101  67  33  0 
0  84  50  16  0

最后,我们对这些数据进行LZ77压缩就可以得到IDAT的正确内容了。
然而,事情并不是这么简单,因为我们研究的是手机上的PNG,如果需要在手机上完成LZ77压缩工作,消耗的时间是可想而知的,因此,我们得再想办法加减少压缩时消耗的时间。
好在LZ77也提供了无压缩的压缩方法(奇怪吧?),因此,我们只需要简单的使用无压缩的方式写入数据就可以了,这样虽然浪费了空间,却换回了时间!
好了,让我们看一看怎么样凑成无压缩的LZ77压缩块:
字节 意义
0~2 压缩信息,固定为0x78, 0xda, 0x1
3~6 压缩块的LEN和NLEN信息
压缩的数据
最后4字节 Adler32信息

其中的LEN是指数据的长度,占用两个字节,对于我们的图像来说,第一个Scan Line包含了5个字节(如第一行的0, 203, 169, 135, 101),所以LEN的值为5(字节/行) * 8(行) = 40(字节),生成字节为28 00(低字节在前),NLEN是LEN的补码,即NLEN = LEN ^ 0xFFFF,所以NLEN的为 D7 FF,Adler32信息为24 A7 0B A4(具体算法见源程序),因此,按照这样的顺序,我们生成IDAT数据块,最后,我们将IHDR、PLTE、IDAT和IEND数据块写入文件中,就可以得到PNG文件了,如图:

(选中的部分为生成的“压缩”数据)
至此,我们已经能够采用最快的时间将数组转换为PNG图片了。
生成的PNG文件:
范例(附源程序)
有效的减少PNG格式文件的大小
通过改变调色板实现类似云彩流动的效果(源程序包含在此jar文件中)


本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/ice197983/archive/2006/07/25/974972.aspx

阅读(1712) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~