📄 base4.htm
字号:
下面是这些部分的内容:<br>
(1)头是一个块,它识别数据流为GIF,并指示恰当地解释后面的数据所需的最早版本的GIF解码程序(87a或89a)。<br>
(2)逻辑程序描述块定义了包围所有后面图像的一个图像平面的大小、纵横尺寸比以及色彩深度(它类似于产生图像的监视器屏幕)。它还指明后面跟随的是否为“全局”色彩表。<br>
(3)全局色彩表(如果存在)构成一个24位RGB元组的调色板(每种底色为一个字节)。如果后面的像没有其自己的“局部”调色板,那么全局色表就是缺省调色板。<br>
(4)后续数据作为“图形”或“专用”块出现。图形块典型地包含一个或多个位图图像,也可能是覆盖的文本。专用块或者包含一个专用应用程序码,或者包含一句不可打印的注释。<br>
(5)最后的尾块只是值为3B(十六进制)的一个字节,表示数据流已结束。<br>
注意:文件中的GIF数据流可能根本就不包含任何位图数据,这时,它只是要传输全局色彩表,作为没有自己调色板的后续数据流的缺省调色板。<br>
这里是一个显示Gif文件的C语言程序,下面的代码是例程gifshow中的主函数部分:<br>
main(argc,argv)<br>
int argc;<br>
char *argv[];<br>
{kk1}<br>
int i;<br>
<br>
if (argc<=1) {kk1}<br>
Sound();<br>
graphinit();<br>
ShowPIC( (char far *)bufptr, Width, Depth);<br>
<br>
if (argc>=3) strcpy(filename, argv[2]);<br>
else {kk1}<br>
strcpy(filename+2, argv[1]);<br>
strncpy(filename, "X_", 2);<br>
if ((strchr(filename,'.')-filename)>8) strcpy(filename+8, ".GIF");<br>
}<br>
for (i=0; i<(1<<BitsPerPixel)*3; i++) pgh->palette[i] <<= 2;<br>
packgif(filename, Width, Depth, BitsPerPixel, pgh->palette, bufptr);<br>
Sound();<br>
<br>
free(buffer);<br>
SetVGAMode(0x03);<br>
exit(0);<br>
return 1;<br>
}<br>
<br>
1.优点 PCX是最老的,因此也是个人电脑软件中得到最为广泛使用的位元映射格式之一。当前的版本可使用24位元彩色,现实最多256色的调色扳或者全24位元的RGB,图形大小最多达64K×64K象点。数据是以运行长度编码(Run-Length
Encoding)压缩。<br>
2.缺点
文件格式没有为储存灰度或彩色校正表留有余地,即不能储存CMYK
(代表青色Cyaneous、紫红Magenta和黄色Yellow三种基本色,加上黑色black作对比)格式数据,也不能储存HSI格式数据[虽然有些Zsoft程序允许使用HSI
(代表色调Hue、饱和度Saturetion和亮度Intensity)来调整彩色值]。它的运行长度压缩方法效率不高,尤其是对于扫描图形或视频信息图形。由于PCX的发展年代较老,
PCX文件可以使用各种调色板技术,但其结果是大多数阅读程序不能处理所有可能的PCX格式图形。<br>
3.变体 PCX随着Zsoft产品的新版本而升级,在文件头(Header)中的一个序码确定了该文件所能使用的Zsoft产品的版本。其中版本0为基本单色(2色)或4色图形;版本2在版本0的基础上加上了16色图形,版本5又加上了24位调色板的256色和全24位RGB彩色。<br>
<br>
一、概述<br>
PCX格式由三个部分组成,即文件头、位图数据(较新版本的)和一个可达256种色彩的调色板。<br>
其文件由固定128字节的文件头开始。它除了版本号以外,还包括被打印或扫描图像的分辨率(单位为每英寸点数)、大小(单位为像素数)、每扫描行字节数、每像素位数和彩色平面数。文件还可能包括一个调色板以及表明该调色板是灰度还是彩色的一个代码。<br>
文件的核心部分是位图数据。位图数据以类似于Packbits
压缩法的运行长度压缩形式记录,像素值通常是单字节的指针,指向调色板中的位置。<br>
如果版本号为5,则文件末尾处还有一个单一的位平面,一个RGB值的256色调色板三种底色各一个字节)。<br>
二、详解<br>
PCX
格式用于写是相对较简单的,但用于读就比较棘手,除非知道被解码图像的很多细节内容(如位深度和调色板等)。因此,以下的阐述都是基于最坏的情况,即读取一个其特性和年代都未确定的PCX文件,所有的数均是little-endian(Intel)格式,即LSB在先。<br>
字节0,Zsoft标志<br>
总是十进制值160,即十六进制A0。<br>
字节1,版本号,<br>
一定程度上不可靠的文件内容指南,见前面一节“变体”的讨论。<br>
字节2,编码<br>
到目前为止,总是为1。当前编码(压缩)方法只有一种,即在下面“位图数据),一节中讲述的运行长度法。<br>
字节3,每像素位数<br>
实际上是每个位平面的每像素位数,可能的值是1、2、4或8。<br>
字节4-11,图像大小<br>
图像大小由最小的和最大的极限给出。通常的下限是0。所有的极限均用16位无符号整数表示,单位为像素。图像大小可以这样计算:XSIZE=Xmax―Xmin+l;
YSIZE=Ymax-Ymin+l,单位为像素。<br>
字节12-15,以每英寸点数为单位的水平和垂直分辨率<br>
这两个16位的数字有点古怪,它们对于定义所存储图像不起任何作用,但是,当它们与图像大小组合起来加以考虑时,能产生出被扫描图像的原始大小,或者被打印图像的希望大小,以英寸为单位。<br>
字节16-63,头调色板<br>
这一字段看上去只适用于带有单一位平面、16种或更少的颜色以及版本号为2的文件(参见下面“解释数据的关键”口节)。使用时,调色板拥有16组三元组的单字节调色板值。<br>
字节65,色彩平面<br>
PCX图像可以是单色彩,也可以是多个色彩平面的(参见第一章)。头的这个字节给出色彩平面数,它是正确翻译PCX文件的关键。<br>
字节66,每行字节数<br>
实际是每个平面的每行的字节数—存储末压缩图像一个扫描行的一个色彩平面所需要内存字节数,它总是偶数。<br>
字节68,头调色板翻译<br>
1=彩色/单色;2=灰度。Paintbrush IV或Paintbrush IV PIus中不使用它。<br>
字节70~73,视屏屏幕大小,X和Y<br>
只被Paintbrush IV和Paintbrush IV PIus使用;并不是必不可少的,但是对于产生正确的外观比例(防止压缩型失真)可能有用。<br>
三、位图数据<br>
如果没有使用调色板,那么数据是实际的像素值;否则,它们是指向调色板值的指针。在后一种情况下,数据给出的是相对于所使用的调色板的起始处的偏移(比如在三字节的三元组值中,1=字节3)。<br>
当数据是实际的像素值时,它们按色彩平面和扫描行存储。例如,对于三种颜色红、绿和蓝(RGB),数据格式为:<br>
(第0行:)RRRRRR...GGGGGG...BBBBBB...<br>
(第1行:)RRRRRR...GGGGGG...BBBBBB...<br>
如果有两个平面,那么色彩是任选的;如果有三个平面,则颜色为RGB;如果使用四个平面,则它们是符合IBM
CGA/EGA标准的单个位的平面:红、绿、蓝和光强(RGBI)。光强位只是给像素以一种名义上较高的亮度。<br>
当数据是指向某调色板指针时,它们就组成一个完整的图像平面(也就是说,它们不会分解成单独色彩平面)。然后数据按如下方式简单地编排(字符P代表各种指针值):<br>
(行0:)PPPPPP<br>
(行1:)PPPPPPP<br>
P的长度取决于深度,以每平面的每像素位数表示。例如,如果深度为4位,则P就是半个字节长。<br>
所有情况下,在扫描行之间都有编码隔断标志。但是,在一个扫描行中的色彩平面间没有编码隔断标志。同样,也没有分隔符可用来标识扫描行的结束(虽然一个扫描行可能是也可能不是用额外的零作为结束)。也就是说,在扫描行之间不会有行号(虽然这里写出来了),也不会有空字符、空格、回车、换行或其他的字符。<br>
不论要记录的是何种类型的位图数据,都使用同样的运行长度压缩方法,下面给出恢复算法(当前普遍使用的基于调色板的图像只有一个平面)。<br>
这里,请您先学习教程,具体了解PCX文件格式,然后来看一下下面这个——例程中由Gif文件转换PCX文件的程序中是如何编写PCX文件头:<br>
WritePcxHeader(FILE *fp,char *palette )<br>
{kk1}<br>
PCXHEAD h;<br>
<br>
memset((char *)&h,0,sizeof(PCXHEAD));<br>
h.manufacturer = 0x0a;<br>
h.version = 5;<br>
h.encoding = 1;<br>
h.xmin = h.ymin = 0;<br>
h.xmax = width - 1;<br>
h.ymax = depth - 1;<br>
h.hres = h.vres = 0;<br>
h.palette_type = 1; <br>
if( BitsPerPixel < 5 ) {kk1}<br>
h.bits_per_pixel = 1;<br>
h.colour_planes = BitsPerPixel;<br>
h.bytes_per_line = pixels2bytes(width);<br>
memcpy(h.palette,palette,(1<<BitsPerPixel)*3);<br>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -