joeguan2 发表于 2007-5-11 13:52

[求助]关于显示256色bmp的问题

256色bmp文件的位图阵列中每一个字节的值代表在颜色表位置,颜色表每一项的结构是R、G、B,每一个占一个字节,这三个就占了3个字节,但在画点函数putpixel(int x,int y,int color)中的color是int类型的,怎样将颜色值转换成putpixel()函数适合的类型?<BR><BR>多谢!!!

ba_wang_mao 发表于 2007-5-11 18:41

就在本网站上有现成的源代码,可运行。

jig 发表于 2007-5-11 18:45

????<BR>楼主只否把概念混淆了?可以再找找BMP格式好好了解一下<BR><BR>256色的BMP也叫8为深元位图,也就是说是0-255共256种颜色(即一个字节表示一个点)。<BR><BR>而在BMP实际数据前有一个条色版信息(他就是RGB的形式表示),你要显示256色BMP图片,就必须先将这个调色板信息给填入相信的显存区<BR><BR>当在高色深下,比如伪真彩16色深模式下共0-65535重颜色,那么这种BMP就没所谓条色板了,他的数据区就是你说的RGB形式表示,而这个也是有多种组合,比如5:6:5,即R占5位,G占6位;B占5位<BR><BR>关于256色的显示你可以在论坛中看看JS256图形包,里面有关于256色图片显示的最简化的源码,相信对你有帮助<BR>

joeguan2 发表于 2007-5-13 14:58

问题已经解决,多谢jig<BR>还有一个小问题<BR>//设置调色板<BR>    fseek(fp,sizeof(BITMAPINFOHEADER)+sizeof(BITMAPFILEHEADER),SEEK_SET);<BR>    fread(bmiColors,4,256,fp);<BR>    for(k=0;k&lt;256;k++)<BR>    {<BR>        outp(0x03C8,k);<BR>        outp(0x03C9,bmiColors[k].rgbRed&gt;&gt;2);<BR>        outp(0x03C9,bmiColors[k].rgbGreen&gt;&gt;2);<BR>        outp(0x03C9,bmiColors[k].rgbBlue&gt;&gt;2);<BR>    }<BR>我用的是open watcom c编译<BR>这里的0x03c8和0x03C9是代表什么端口?

ba_wang_mao 发表于 2007-5-14 13:12

<P>七.设置颜色寄存器</P>
<P>我们知道VGA显示卡具有显示256种颜色的能力,每种颜色能够用一个0-255之间的数值来表示,那么这些数值与我们在屏幕上实际见到的颜色之间有什么关系呢?其实这些数值只是VGA显示卡上的颜色寄存器的索引值,颜色寄存器里才保存了屏幕上颜色的真实值。VGA显示卡上有一个包含256个单元的颜色寄存器(又称为调色板),每个单元由三部份组成,这三部份分别代表颜色中的红、绿、蓝三种成份(显示器就是用这三种成份来组成任何我们所看到的颜色),用三个字节表示,颜色寄存器一共有768个字节(3*256=768)。当我们要在屏幕上显示某种颜色时,显示卡硬件就根据颜色的索引值在颜色寄存器中查找,找到后再从相应单元中取出颜色值显示在屏幕上,这个过程与画家使用调色板相似,颜色寄存器相当于调色板,颜色寄存器中的单元相当于调色板上的色格,在色格中装有预先调好的颜色,当画家需要用某种颜色作画时,就从装有那种颜色的色格中把颜色取出来。例如,我们要显示颜色索引值为30的颜色,显示卡硬件就去查找颜色寄存器的第30单元,30单元位于距颜色寄存器首址3*30=90处(因为每个单元有三个字节),然后取出90处记录有红、绿、蓝三种成份的三个字节作为在屏幕上显示的色彩信号。但是实际上每个字节只用了六位来表示颜色,其它两位没用,这六位表示的数的值域为0-63,所以每种颜色(红、绿、蓝)成份具有64种亮度的表现能力,三种颜色成份组合共可以产生64*64*64=262,144种颜色(VGA 13H模式从这262,144种颜色中取出256种在同一屏幕上显示)。我们可以通过事先设置颜色寄存器的值来使用我们自己的颜色。 <BR>设置颜色寄存器有多种方法,如调用BIOS功能,但是这种方法速度比较慢,游戏设计中通常采用直接访问VGA显示卡的I/O端口的方法来快速设置颜色寄存器,我们只需访问四个I/O端口就可以完成设置颜色寄存器的工作。这四个端口分别是: 0x3c6、0x3c7、0x3c8和0x3c9。<BR>端口0x3c6称为调色板屏蔽寄存器,用来屏蔽所要求的调色板寄存器的位,如果你在这个寄存器中放入0xff,你就可以通过调色板索引寄存器0x3c7和0x3c8(一个用于读,一个用于写)访问任何你希望访问的颜色寄存器,端口0x3c9称为调色板数据寄存器,红、绿、蓝三种成份就是通过它进行读写(颜色值要读或写三次)。</P>
<P>我们定义一个结构来方便处理颜色寄存器:</P>
<P>typedef struct RGB_COLOR<BR>{<BR>unsigned char red;<BR>unsigned char green;<BR>unsigned char blue;<BR>}RGBColor,*RGBColorPtr;</P>
<P>结构中的red、green和blue变量用来保存颜色的红、绿、蓝三种成份。</P>
<P>设置颜色寄存器值的函数:</P>
<P>void SetPaletteRegister(int index,RGBColorPtr color)<BR>{<BR>outportb(0x3c6,0xff);<BR>outportb(0x3c8,index);<BR>outportb(0x3c9,color-&gt;red);<BR>outportb(0x3c9,color-&gt;green);<BR>outportb(0x3c9,color-&gt;blue);<BR>}</P>
<P>获取颜色寄存器值的函数:</P>
<P>void GetPaletteRegister(int index,RGBColorPtr color)<BR>{<BR>outportb(0x3c6,0xff);<BR>outportb(0x3c7,index);<BR>color-&gt;red=inportb(0x3c9);<BR>color-&gt;green=inportb(0x3c9);<BR>color-&gt;blue=inportb(0x3c9);<BR>}</P>

joeguan2 发表于 2007-5-15 10:12

非常感谢ba_wang_mao的详解!!!

页: [1]

编程论坛