VC++ 下的 BMP 格式图像和 PNG 格式图像的转换

2016-06-26 11:10:33肖峰
赤峰学院学报·自然科学版 2016年3期
关键词:霍夫曼字节编码

肖峰

(安徽大学; 安徽职业技术学院 学生处,安徽 合肥 230001)

VC++ 下的 BMP 格式图像和 PNG 格式图像的转换

肖峰

(安徽大学; 安徽职业技术学院 学生处,安徽 合肥 230001)

初步探讨了在 VC++的 BMP 格式图像和 PNG 格式图像的转换.首先分析了 BMP 和 PNG 两种图像文件的详细格式,然后在 VC++环境下建立了这两种图像格式文件的处理类 CBmp 和 CPng,在这两个类中实现了 BMP 文件的读取、显示和 PNG 文件的保存等操作.在理解 LZ77 压缩算法和霍夫曼编码算法的基础上,在 VC++的环境下实现这两种算法.这样,我们就可以读取 BMP 图像文件,然后将图像显示在程序界面上,通过压缩和编码,从而将对应的 BMP 图像数据转换为PNG 图像数据,实现了图像格式的转换.

VC++;BMP;PNG;LZ77 算法;霍夫曼编码

随着网络的发展,图像越来越成为人们之间重要的信息传输和共享方式.在生活和工作中经常用到的图像格式有BMP、PNG、jpe、gif和 tiff等等.其中 BMP 和 PNG 格式是采用的无损压缩图像格式,它们之间格式的互相转换就成了数字图像处理中经常遇到的问题.

1 BMP格式分析

BMP是最常用最基本的图像文件格式,图像软件基本上都能读取和显示BMP图像格式.和其他图像格式相比,BMP格式是一种非常简单的格式,设计目的是为了能在程序设计中轻松的进行图形编程.它具有比较足够的颜色深度支持,可以支持 1 位、2 位、4 位和 8 位的彩色索引图像以及16 位、24 位和 32 位的真彩 RGB 图像.BMP 格式的图像通常都很大,因为他只在4位和8位彩色索引图像中支持最简单的行程编码格式.

一般来说BMP图像文件由四部分组成:

1.1 位图文件头

BMP文件的位图文件头是一种简单的供应用程序识别BMP 文件的文件头.它保存了 BMP 文件签名、文件长度字段和数据等相关信息.

1.2 位图信息头

位图信息头保存了真正的图像信息,它存储了相关的图像格式、图像大小、压缩方式和颜色说明信息等等.

1.3 颜色表

这部分在图像文件中不是必须的,有些高彩或者真彩图像是不需要颜色表的.对于少于 256 色的图像,位图数据中的像素就是颜色表的索引,用于将索引值转换成 RGB 值.

很多时候会把位图信息头和颜色表组合在一起组成位图信息结构.这里需要指出的是由于位图信息的位图信息头字段的定义在不同的系统或者平台上可能存在定义版本不一致的情况,应用程序不应该依靠位图信息去定位位图颜色表,而是应该在运行时根据图像信息头计算出颜色表的偏移量.

1.4 位图数据

位图数据是图像实际像素保存的地方.通常情况下,图像是对齐到32位边界的扫描线的序列.扫描线的默认次序是由下向上.由下向上表示位图数据中的第一个像素实际上是在屏幕上显示时最后一行扫描线的第一个像素.在每行扫描线内部,像素被压缩在一起以节省空间.由于扫描线是双字节对齐的,在扫描线的结尾可能会加上更多的位将其凑成双字的整数倍.对于使用颜色表的位图,像素数据就是颜色表中的颜色索引值,其他的真彩位图中直接使用 RGB 值.

2 BMP文件的读取

利用 VC++ 实现 BMP 文件的读取、显示和保存,先用VC++ 创建一个文档视图应用程序,所有的功能都会在这个程序中实现.

首先我们实现一个 BMP 文件操作的类 CBmp,包括Bmp.h 和 Bmp.Cpp 文件.

其次通过 File 菜单下的打开子菜单来打开 BMP 文件,通过类函数 Read()来判断文件是否打开成功.如果返回值为负,则是读取打开文件失败,则提示打开 BMP 文件失败.如果返回值为正,则是正确打开 BMP 文件,程序继续向下执行.

最后通过消息函数来调用类 CBmp 的 Draw()函数来把BMP文件的内容显示到界面上.

这样,一个 BMP图像文件就被读取显示在程序中了.

3 PNG 文件格式

PNG 是一种无损压缩的、易传输的光栅图像文件格式,设计目的是用来替代 GIF 和 TIFF 文件格式,并增加一些这两种所不具有的文件特性.PNG 图像文件是现在网络、媒体、游戏中最常用的文件格式之一.

相比 BMP 格式文件,PNG 格式文件显得更复杂些.它支持灰度图像、索引彩色图像和真彩图像,并且支持额外的 α通道.采样的深度范围是从 1 位到 16 位.采用的压缩算法是LZ77 派生的无损数据压缩算法.

3.1 文件结构

PNG 数据流包含 PNG 文件签名和数据块序列,每个数据块都有自己的类型和功能.

3.1.1 PNG 文件签名

PNG 文件签名包含一个 8字节的数据,用来识别该文件是不是 PNG 文件.

3.1.2 数据块

PNG 包含两种类型的数据块,一种叫关键数据块,有 4种.在每个 PNG 文件中都必须必须包含这四种数据块,另一种叫做辅助数据块,有 14 种,PNG 文件中可以包含也可以不包含,可以包含一种也可以同时包含多种.

关键数据块有以下类型:文件头 (IHDR)、调色板(PLTE)、图像数据(IDAT)和图像结束数据(IEND).

辅助数据块包含了很多信息,这些辅助数据块在 PNG文件中根据需要被包含一部分或者全部包含.

数据块结构

每个数据块由3个或者4个部分组成:

Length:4 字节,块中数据的长度,可以为 0

Chunk Type Code(类型码):4 字节,取值范围 65~90 和97~122

Chunk Data(数据块数据):可变,数据段

CRC:4 字节,循环冗余校验码

数据块解析

下面我们对四种类型的关键数据块进行解析.

(1)IHDR:文件头数据块,按照 PNG 文件规范,整个数据流或者文件中只能有一个文件头数据块.而且它是首个出现在数据流中数据块,数据块的构成格式如下:

Width、Height:宽和高,都是 4 字节

Bit depth:1 字节,图像采样或调色板索引的位数

ColorType:1 字节,图像类型

Compression method:1 字节,压缩方法,目前定义了一种压缩方法

Filter method:1 字节,目前只定义了一种滤波器方法,0

Interlace method:1 字 节 0 是 没 有 Interlace,1 是 采 用Adam7 方法

(2)PLTE:调色板数据块,如果文件是真彩图像或者包含α数据通道的真彩图像,调色板数据块不是必须存在的,如果文件是索引彩色图像,调色板数据块是存在的.调色板数据块包含从 1 到 256 个调色板信息,每一个调色板信息由3个字节组成.

(3)IDAT:图像数据块,它存储着压缩后真正的图像数据,可以有多个图像数据块,但是在 PNG 数据流中必须以连续顺序的方式存放.

(4)IEND:图像结束数据:放在文件的尾部,是文件结束的标志.它的数据域部分必为空.

关于辅助数据块的详细解析这里不再一一列举.

3 LZ77 派生算法的实现

3.1 基本原理

PNG 使用的是 LZ77 算法派生的一个叫 DEFLATE 的无损压缩算法.DEFLATE 实际上是两种算法的组合实现,它先用 LZ77 算法进行预处理,然后用霍夫曼编码,快速的得到非常不错的压缩效果.

LZ77 的基本原理如下:它引入滑动窗口的概念,把这个滑动窗口作为一个动态的字典来维护,用一个三元符号组来表示 offset,len 和分割符.offset表示从文件起始位置到当前 Phase 的起始位置的距离,len 记录当前 Phase 有多少个字符,分割符仅用于分割不同的 Phase.Phase 就是 offset到offset+len 之间的子串减掉分隔符.

霍夫曼编码的基本原理:首先要把整个文件中每个符合出现的次数统计下来.然后根据这些符号的次数和出现频率,建立霍夫曼树,通过霍夫曼树生成每个符号的编码.在文件中出现频率高的符号,它对应的霍夫曼编码的长度比较短.对于文件中出现频率低的符号,它的霍夫曼编码的长度比较长.此时再读入一遍文件,逐个编码,得到的码流就是压缩后的数据.

3.2 实现过程

下面用伪代码来示意 LZ77 的算法过程:

假设我们用一个三元组 (i,j,X) 来表示上面提到的三元组.

关于霍夫曼编码这里不再赘述.

4 VC++实现从 BMP 到 PNG 转换

在 VC++ 中实现从 BMP 格式到 PNG 格式的转换,是基于前面的 BMP 文件读取显示保存操作和 LZ77 算法与霍夫曼编码实现的基础之上的,并且同时要求分析 PNG 文件的详细格式和读写方法,利用前面建立的 VC++ 下的文档视图程序具体实现这个过程.

首先建立基本的应用程序和 CBmp、CPng 类,把类CBmp 和 CPng的成员变量和成员函数初始化.

其次把 LZ77 压缩算法和霍夫曼编码算法用 VC++ 代码实现,确保下面的数据处理能正确进行.

最后,当前面的这些准备工作完成以后,将 BMP 图像文件中的图像数据通过 CBmp类读出来,通过编码程序转换为 PNG 图像数据,并将 BMP 的图像信息写入 PNG 文件的对应域的值,通过 CPng 类的方法将之保存为 PNG 格式文件.

5 结论

首先进行的是读取 BMP文件的操作.在分析和理解BMP 文件的格式以后,我们创建了一个 VC++ 的应用程序,并且实现了详细的类 CBmp用于 BMP 的操作.接下来我们解析了 PNG 文件的格式和其相关的压缩算法,创建和实现了类 CPng 和 LZ77 派生算法的处理函数.最后在 VC++ 实现BMP 图像格式文件向 PNG 图像格式文件的转换.

〔1〕韩姣.基 于 VC++的 BMP 格 式图像与 GIF 格 式图 像 转换[J].武汉理工大学学报,2007,29(12):23-25.

〔2〕(美)Feng Yuan.Windows 图 形 编 程 [M].北 京 :机 械 工 业出版社,2002.

〔3〕(美)怀特著,杨浩等.GDI+程序设计[M].北京:清华 大学出版社,2002.

TP317.4

:A

:1673-260X(2016)02-0017-02

2015 年 10 月 9 日

猜你喜欢
霍夫曼字节编码
No.8 字节跳动将推出独立出口电商APP
基于SAR-SIFT和快速稀疏编码的合成孔径雷达图像配准
《全元诗》未编码疑难字考辨十五则
子带编码在图像压缩编码中的应用
电子制作(2019年22期)2020-01-14 03:16:24
抽象表现主义艺术先驱——汉斯·霍夫曼
少儿美术(2019年5期)2019-12-14 08:04:52
No.10 “字节跳动手机”要来了?
Genome and healthcare
诺奖得主霍夫曼团队落户深职院
简谈MC7字节码
枪口下的人格