Internet常见图像格式及其在Linux上的处理

图象格式简介 kerberos 软件工程师, 蓝点软件北京研发部 2001 年 2 月
许 多应用程序需要处理 Internet上的图象信息。这些图象信息通常以特定的格式保存,常见的有GIF、JPEG、PNG等等。由于各种图象文件格式的特殊性,大大增加了编 程处理的难度。为了帮助开发人员理解和处理这些图象信息,本文介绍了常见的图形格式以及相关概念,并介绍了如何在Linux系统中使用已有的图象处理函数 库方便处理这些图象。全文共分两部分。第一部分介绍了Internet上常见的三种图像格式:GIF、JPEG、PNG;第二部分介绍这些图象的编程处 理。

1简介 随着互联网的发展,信息交换也从最初的以文字开始逐渐发展到了文字、图像、声音、视频的多媒体信息交换。可以毫不夸张地说,图像在整个信息交换中的重要 性,仅次于文字。由于以往图像的体积很大,加之网络带宽的限制,使得图像的传输技术的发展速度很快。现在,网络上流行的图像格式主要是jpeg、png、 gif三种。

最简单、最常见同时也是最容易处理的图像文件格式莫过于位图,一个位图文件记录了图像的宽度、长度、色深以及以RGB方式表示的每一象素的颜色。位图是一 种基本的图像格式,所以在许多平台上,包括Windows、X Window、MacOS上都提供了大量处理位图的API。由于位图是使用RGB方式描述一个像素点的颜色,所以位图的体积很大,相对于有限的网络带宽来 说,要传输一副位图,会浪费很多的网络资源。当然,你可能会说,何不使用压缩算法压缩之后进行传输?很好,使用压缩技术的确可以减小图像的体积,以后我们 介绍的几种图像的格式中,都使用了压缩的技术。但是,基于RGB颜色描述一个像素的方式导致了位图这种图像的先天不足,同样使用压缩技术,还有很多的颜色 表示方法比RGB更优秀。

对于颜色的表示,一种非常简洁的方法是使用颜色索引,所谓颜色索引是在图像的文件中提供一个或者多个调色板,调色板用RGB方式记录了整幅图像用到的所有 的颜色,图像中的象素的颜色就通过调色板的索引来表示。这样,就大大减小了图像文件的体积,再配合压缩技术,图像的体积还可以减小。

在图像中使用的压缩有有损压缩和无损压缩两种压缩方式,有损压缩的图像,压缩比比较大,但是图像会有失真,因为它是使用了与像素相近的颜色来代替像素的真 实的颜色,这样节省了色彩空间,jpeg图像就是典型的有损压缩的图像,其压缩比甚至高达20:1。无损压缩仅仅是对存储像素的颜色的数据进行压缩压缩以 后的数据在显示的时候还需要解码器进行还原。在gif、png等图像格式中,都使用了一些这样的算法。

2 图像格式简介

2.1gif

CompuServe公司制定的Gif 图像格式的全称是 'GraphicsInterchangeFormat' ,顾名思义,是为Internet上传输高质量的图像。它共有两个版本:gif87a 和gif89a。在Gif图像格式中,所有的数据都是以流的方式传送的,并且Gif 定义了许多分隔符把数据流分割成数据块。Gif数据块主要有以下几种:

  • Gif 文件签名块:Gif图像的标识,包括Gif的签名标识和Gif文件格式的版本。
  • 逻辑屏幕描述数据块:描述了逻辑屏幕的尺寸,包括以逻辑象素表示的逻辑屏幕的左上角坐标、长度和宽度。
  • 全局调色板数据块;包括以RGB方式描述的全局调色板。
  • 局部调色板数据块;包括以RGB方式描述的应用于局部某一帧的局部调色板。
  • 图像描述块:包含以逻辑象素表示的此帧图象在逻辑屏幕上的左上角的位置及其长度和宽度。
  • 光栅数据数据块;包括具体的图象数据,每一象素在调色板中的颜色索引。
  • 数据流结束数据块;标志Gif数据流的结束

在Gif89a版本中,还增加了

  • 图像扩展控制数据块;对gif图像各帧的控制标志,包含了图象的扫描方式为顺序扫描或者交错扫描。
  • 注释数据块;注释文本
  • 文本数据块;包含了图像中的文字
  • 应用程序自定义数据块;包含应用程序自己定义的数据。

Gif图像最多可支持256色,在光栅数据数据块中,使用了LZW压缩算法对光栅数据进行压缩。在图像控制数据块中,还定义了gif 图像的扫描顺序是否是交错扫描,这样在网络传输速度比较慢的情况下,允许一幅gif图像可以先显示主要的部分,最后显示出全部。

对于gif图像的处理,我们需要编写解码器来处理不同的数据块,把它转换成方便应用程序处理的格式。解码器的编写十分复杂,但是linux 下已经有很多方便自由的处理库,libgif 就是其中的佼佼者。我们可以直接使用这些函数库。后面面,我们会介绍一下libgif 的使用。或者如果你有特殊的需要,你可以自己编写解码器,但是通常,没有什么必要。

2.2png

gif虽然是一个很优秀的图像格式,但是由于牵扯到CompuServe公司的版权问题,在网络上引出了不少的纠纷。于是另外一个图像格式出现了,就是png。Png的全称是 'Portable Network Graphics' ,除了可以自由使用以外,png还有许多比gif更强劲的功能,如支持16位24位色彩空间、 Chanel、Alpha、Gama处理等。

Png也是以数据流的方式传输的,与gif相似,png也把数据流分解成若干数据块。在png数据流的开始是png 图像格式的签名。后面的数据块的顺序除了因为依赖性的原因之外,出现的顺序是无关紧要的。在每一Png图象文件流的开始是Png的文件签名,然后是IHDR数据块,后面是其他的一些数据块,Png文件的最后是IEND-文件结束数据块。

每一Png数据块的结构如下:

  1. 数据块长度字段;
  2. 数据块类型字段;
  3. 数据块内容字段;
  4. CRC校验码;

其中数据块长度字段仅仅指数据块内容的字节数,而不包含其本身与数据块类型字段和CRC校验码字段的长度。这些字段的长度都是固定的4 byte。
需要注意的是数据块类型字段,这个字段是由4个ASCII字符组成,每个ACSII字符的大写方式和小写方式具有不同的含义。Png解码器需要根据没个字 符的大小写方式选择不同的处理方式。第一个字符的大写方式表示此数据块为一重要数据块,如果解码器不能识别这个类型,则解码失败。反之,小写的则为非重要 数据块,解码器可以选择忽略这个数据块。第二个字符的大小写则反映出此数据块是否为png 图像的公有数据块,第三个为保留标志,此字符始终为大写字符,第四个字符的大小写则表示此数据是否可以任意拷贝。
以下是主要的 png 图像数据块类型:
重要数据块:

  • IHDR: 描述了PNG 图像的大小/颜色空间、压缩算法/行扫描方式等信息,一般先出现在Png文件签名数据块之后。
  • PLTE: 包含以后图象数据块IDAT中的图像数据所使用的调色板,在使用颜色索引(在IHDR数据块中指明使用何种颜色空间)方式的情况下,必须在IDAT数据块之前出现。
  • IDAT: 图像的数据,具体的表示方式由IHDR中指定,一幅图象可以由数个IDAT数据块组成,但是这些数据块必须是连续的。
  • IEND: 图像的结束标志,出现在文件的最后。这个数据块没有实际的数据段。

非重要数据块:

  • bKGD: 图像的背景颜色;
  • cHRM : 显示校正数据块,用于实现设备无关性。
  • gAMA : gama特殊显示数据块
  • hIST: 当用以模拟调色板不能满足需要的颜色
  • pHYs:推荐显示的环境
  • sBIT: 特殊像素数据
  • tEXt : 保存在图像中的一些文本
  • tIME : 图像最后修改时间
  • tRNS : 透明处理
  • zTXt:压缩过的tEXt

比之gif ,png更强大,也更复杂。当然linux下也有libpng函数库,我们可以方便的使用它。后面我们也会介绍一下libpng的使用。

2.3Jpeg

与前面两种图像格式不同,jpeg是一种有损压缩方式的图像。它是由静态图像专家小组规定的一个文件格式,目的是提供高压缩比的图像。Jpeg 同时也是静态图像专家小组的简写。

于前面的两种图象的描述方式不同,Jpeg使用的颜色空间是YCrCb空间,同Mpeg使用的YUV12颜色空间相似。由于人的眼睛对于亮度远比对色度敏感,所以使用YCrCb颜色空间可以在不影响视觉效果的情况下,适当的进行压缩。

YCrCb到RGB的转换矩阵是


| Y | |0.299 0.5870.114|| R | | 0 |
| Cb|=|- 0.1687- 0.3313 0.5| *| G | + |128|
| Cr| |0.5 - 0.4187- 0.0813|| B | |128|

Jpeg图象的格式也是以每一数据段来描述的,在Jpeg文件的开始,是SOF数据标志,文件最后以EOF标志结束。每一数据段都以0xff表示开始,最后以非零值或者0xff结束。数据段最后的结束标志的不同表示了数据段的意义。主要有一下几种:

  • FFD8: SOF数据段,包含了图象的精度,尺寸,长度等信息
  • FFD9: EOF 数据段,表示文件结束
  • RST1~RST7, FFD1~FFD7:复位数据标志
  • FFE0:保留数据块
  • FFFE:文件注释数据块
  • FFDB:量化表数据块
  • FFDC:图像行数数据块
  • FFDD:复位间隔数据块
  • FFC4: haffman 表数据块

Jpeg的编码方式是以上的三种图象格式中是最复杂的,其中运用许多的复杂的数学运算,幸运的是,即使你对那些运算一无所知,只要你对图象的格式有一些了解,也可以在程序中处理它,当然是使用已经具有的函数库-libjpeg.

在本文的第二部分,我们将介绍在 Linux 上处理以上三种图象的三个函数库,libgif、libpng 和 libjpeg.

参考资料

关于作者 Kerberos,软件工程师,任职于蓝点软件技术(北京)研发中心。欢迎读者和我取得联系(kerberos@minigui.org)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值