编程论坛's Archiver

ba_wang_mao 发表于 2007-1-24 15:34

800X600X256色下24K真彩色BMP图片为什么显示不出来?(本子程序256色BMP图片显示正

<P>请帮忙指导一下,我查阅了好多资料都找不到正解!<BR><BR>/*第一部分为位图文件头BITMAPFILEHEADER,其定义如下:*/<BR>typedef struct tagBITMAPFILEHEADER<BR>{<BR>    unsigned int bfType;            /*指定文件类型,*.bmp文件的头两个字节都是"BM"*/<BR>    unsigned long bfSize;            /*指定文件大小,包括这14个字节*/<BR>    unsigned int Reserved1;            /*为保留字,不用考虑*/<BR>    unsigned int reserved2;            /*为保留字,不用考虑*/<BR>    unsigned long bfOffset;            /*为从文件头到实际的位图数据的偏移字节数,前三个部分的长度之和。*/<BR>}BITMAPFILEHEADER;</P>
<P>/*第二部分为位图信息头BITMAPINFOHEADER,这个结构的长度是固定的,为40个字节其定义如下:*/<BR>typedef struct tagBITMAPINFOHEADER<BR>{<BR>    unsigned long biSize;            /*指定这个结构的长度,为40*/<BR>    unsigned long biWidth;            /*指定图象的宽度,单位是象素*/<BR>    unsigned long biHeight;            /*指定图象的高度,单位是象素*/<BR>    unsigned int biPlanes;            /*必须是1,不用考虑*/<BR>    unsigned int biBitCount;        /*指定表示颜色时要用到的位数,常用的值为1(黑白二色图),4(16色图),8(256色),24(真彩色图)*/<BR>    unsigned long biCompression;    /*指定位图是否压缩,有效的值为BI_RGB,BI_RLE8,BI_RLE4,BI_BITFIELDS*/<BR>    unsigned long biSizeImage;        /*指定实际的位图数据占用的字节数*/<BR>    unsigned long biXpolsPerMeter;    /*指定目标设备的水平分辨率,单位是每米的象素个数。*/<BR>    unsigned long biYpelsPerMeter;    /*指定目标设备的垂直分辨率,单位同上。*/<BR>    unsigned long biClrUsed;        /*指定本图象实际用到的颜色数,如果该值为零,则用到的颜色数为2的biBitCount次方。*/<BR>    unsigned long biClrImportant;    /*指定本图象中重要的颜色数,如果该值为零,则认为所有的颜色都是重要的。*/<BR>}BITMAPINFOHEADER;</P>
<P><BR>typedef struct tagRGBQUAD            /*用于读取调色板信息*/<BR>{<BR>    unsigned char rgbBlue;<BR>    unsigned char rgbGreen;<BR>    unsigned char rgbRed;<BR>    unsigned char Reserved;<BR>}RGBQUAD;</P>
<P>typedef struct tagRGB<BR>{<BR>    unsigned char r;<BR>    unsigned char g;<BR>    unsigned char b;<BR>}RGB24;<BR><BR><BR>我依照NEO的子程序,可是24K的BMP图片显示不出来,请指点?</P>
<P>#define SRGB332(r, g, b) ((((r) / 9) &lt;&lt; 5) + (((g) / 9)&lt;&lt;2) + (b) / 21)</P>
<P>void Show_BMP(char *File_Name, int x, int y)<BR>{<BR>    int i, j, width, color,len;<BR>    FILE *fp;<BR>    unsigned char *buffer;<BR>    RGB24 *RGB_buffer;<BR>    RGBQUAD *RGB;<BR>    BITMAPFILEHEADER *FileHead;<BR>    BITMAPINFOHEADER *InfoHead;</P>
<P>    if ((fp=fopen(File_Name,"rb")) == NULL)<BR>    {<BR>        printf("BMP File not exist ...");<BR>        return;<BR>    }<BR>    RGB = (RGBQUAD *)malloc(sizeof(RGBQUAD));<BR>    FileHead = (BITMAPFILEHEADER *)malloc(sizeof(BITMAPFILEHEADER));<BR>    InfoHead = (BITMAPINFOHEADER*)malloc(sizeof(BITMAPINFOHEADER));<BR>    fread(FileHead,sizeof(BITMAPFILEHEADER),1,fp);<BR>    if (FileHead-&gt;bfType!='BM')<BR>    {<BR>        printf("BMP File type Error ...");<BR>        return;<BR>    }<BR>    fread(InfoHead,sizeof(BITMAPINFOHEADER),1,fp);<BR>    if (InfoHead-&gt;biCompression !=0 || (InfoHead-&gt;biBitCount!=8 &amp;&amp; InfoHead-&gt;biBitCount!=24))<BR>    {<BR>        printf("BMP File not Support Compression type ...");<BR>        fclose(fp);<BR>        return;<BR>    }<BR>    width =((int)InfoHead-&gt;biWidth+3)/4*4;    // 每行字节数--4的整数倍<BR>    if ((buffer = (unsigned char *)malloc(width)) == NULL) // 申请缓冲区<BR>    {<BR>        fclose(fp);<BR>        return;<BR>    }<BR>    if ((int)InfoHead-&gt;biBitCount == 8)  // 色深=8<BR>    {<BR>        for (i = 0 ; i &lt; 256 ; i++)<BR>        {<BR>            fread(RGB,sizeof(RGBQUAD),1,fp);<BR>            outportb(0x3C8,i);<BR>            outportb(0x3C9,RGB-&gt;rgbRed&gt;&gt;2);<BR>            outportb(0x3C9,RGB-&gt;rgbGreen&gt;&gt;2);<BR>            outportb(0x3C9,RGB-&gt;rgbBlue&gt;&gt;2);<BR>        }<BR>        for (j = (int)InfoHead-&gt;biHeight-1 ; j &gt;= 0 ; j--)<BR>        {<BR>            fread(buffer,width,sizeof(unsigned char),fp);<BR>            for (i = 0; i &lt; width; i++)<BR>                PutPixel(i+x,j+y,buffer[i]);<BR>        }<BR>    }<BR>    else if ((int)InfoHead-&gt;biBitCount == 24)  // 色深=24<BR>    {<BR>        len=(int)InfoHead-&gt;biWidth*sizeof(RGB24)+(int)InfoHead-&gt;biWidth&amp;3;<BR>        if ((RGB_buffer = (RGB24 *)malloc(len)) == NULL)<BR>        {<BR>            fclose(fp);<BR>            return;<BR>        }<BR>        for (j = (int)InfoHead-&gt;biHeight-1 ; j &gt;= 0 ; j--)<BR>        {<BR>            fread(RGB_buffer,len,sizeof(char),fp); /*读取该行像素的所有点的颜色*/<BR>            for (i=0;i&lt;len;i++)<BR>            {<BR>                color = SRGB332(RGB_buffer[i].r,RGB_buffer[i].g,RGB_buffer[i].b);<BR>                PutPixel(i+x,j+y,color);<BR>            }<BR>        }</P>
<P>    }<BR>    free(FileHead);<BR>    free(InfoHead);<BR>    free(RGB);<BR>}</P>

一笔苍穹 发表于 2007-1-24 17:03

<P>你得到的是什么错误,还是只是显示的不正确?</P>

ba_wang_mao 发表于 2007-1-24 17:41

256色的BMP图片本子程序能显示出来,而且显示正确,只是24K的BMP图片显示不出来,屏幕是黑的。最后按一键后,能够返回。

ba_wang_mao 发表于 2007-1-25 08:46

<P>256色的BMP图片本子程序能显示出来,而且显示正确,只是24K的BMP图片显示不出来,也就是当色深=24时,图片显示不出来,屏幕是黑的,程序没有错误,只是24K图片处理不正确(不知道如何处理),导致图片无法正确显示。<BR>  以下是色深=24时的程序片段:<BR>typedef struct tagRGB<BR>{<BR>    unsigned char r;<BR>    unsigned char g;<BR>    unsigned char b;<BR>}RGB24;<BR><BR>#define SRGB332(r, g, b) ((((r) / 9) &lt;&lt; 5) + (((g) / 9)&lt;&lt;2) + (b) / 21)<BR>RGB24 *RGB_buffer;<BR><BR>else if ((int)InfoHead-&gt;biBitCount == 24)  // 色深=24<BR>{<BR>   len=(int)InfoHead-&gt;biWidth*sizeof(RGB24)+(int)InfoHead-&gt;biWidth&amp;3;<BR>   if ((RGB_buffer = (RGB24 *)malloc(len)) == NULL)//申请内存空间<BR>   {<BR>       fclose(fp);<BR>       return;<BR>   }<BR>   for (j = (int)InfoHead-&gt;biHeight-1 ; j &gt;= 0 ; j--)// 图片高度循环<BR>   {<BR>       fread(RGB_buffer,len,sizeof(char),fp); /*读取该行像素的所有点的颜色*/<BR>       for (i=0;i&lt;len;i++)//图片宽度循环<BR>       {<BR>           color = SRGB332(RGB_buffer[i].r,RGB_buffer[i].g,RGB_buffer[i].b);<BR>           PutPixel(i+x,j+y,color);<BR>       }<BR>   }<BR>}</P>

ba_wang_mao 发表于 2007-1-26 17:30

为什么24K真彩色BMP图片显示不出来了,有谁知道?

ba_wang_mao 发表于 2007-1-30 16:41

为什么24K真彩色BMP图片显示不出来了,有谁知道

jig 发表于 2007-2-11 11:22

<P>你是想直接在32模式去现实显示还在想在256色下采用抖动法显示24位图片?</P>
[align=right][color=#000066][此贴子已经被作者于2007-2-11 11:23:16编辑过][/color][/align]

ba_wang_mao 发表于 2007-2-12 08:46

我想在256色下采用抖动法显示24位图片,由于首次接触MSDOS下编程显示BMP图片,因此很多概念不清楚,

ba_wang_mao 发表于 2007-2-12 10:48

<P>第一步:我用《XnView V1.4》软件将一幅24K真彩色BMP图片按照如下步骤:图像--&gt;转换为彩色[C]--&gt;256色抖动 后另存文件生成一幅新图片。<BR>第二步:<BR>  (1).定义一个宏makecol16<BR>#define makecol16(r,g,b) ((((unsigned int)(r)&gt;&gt;3)&lt;&lt;11) + (((unsigned int)(g)&gt;&gt;2)&lt;&lt;5) + ((b)&gt;&gt;3))<BR>    (2).定义24K的RGB<BR>        typedef struct  tagRGB16M            /* 16M RGB像素类型 */<BR>        {<BR>          unsigned char Blue;<BR>          unsigned char Green;<BR>          unsigned char Red;<BR>        }RGB16M;<BR>    (3).然后将读出的三字节颜色(RGB)转换,往VRAM中填充<BR>    else if ((int)InfoHead-&gt;biBitCount == 24)    //    色深=24(真彩色图片)<BR>    {<BR>        register RGB16M *buffer;<BR>        if ((buffer = malloc(width*sizeof(RGB16M))) == NULL)<BR>        {<BR>            fclose(fp);<BR>            return;<BR>        }<BR>        for (j = (int)InfoHead-&gt;biHeight-1 ; j &gt;= 0 ; j--)<BR>        {<BR>            fread(buffer,width,sizeof(RGB16M),fp);<BR>            for (i = 0 ; i &lt; width ; i++)<BR>            {<BR>                color = makecol16(buffer[i].Red,buffer[i].Green,buffer[i].Blue);<BR>                PutPixel(i,j,color);<BR>            }<BR>        }</P>
<P>    }<BR><BR>还是显示花屏,请指出错误之处</P>

RockCarry 发表于 2007-2-12 11:18

<P>在256色视频模式下,显示24bit色bmp图片,方法如下:<BR>可以不用XnView V1.4对图片进行处理,而在程序中直接进行处理:<BR>    1. 设置256色的调色板为332像素格式的调色板<BR>    2. 对24bit色bmp中的每一个像素进行转换:24bit(888) -&gt; 8bit(332)<BR>    3. 将转换以后的8bit颜色值绘制到屏幕的正确位置上<BR>    3. 正确处理完图片中的每一个像素点,就ok了<BR><BR>        RockCarry<BR>        2007-2-12<BR><BR></P>

RockCarry 发表于 2007-2-12 11:34

上面讲的是抖动处理的方法,当然也可以使用最佳匹配的算法,以获得更好的显示效果。<br>方法如下:<br>    1. 统计一个bmp中各个颜色出现的频率<br>    2. 将颜色频率按从高到底进行排序(sorted color table - SCT)<br>    3. 将显示器256色的调色板设置为SCT表中的前256项 (将这256项记为SCT256表)<br>    4. 对原24bit bmp中的每个像素点进行如下处理:<br>       根据该像素的RGB值,在SCT256中查找一个最佳匹配的颜色值,并取得该颜色值在SCT256中的编号(8bit)<br>       将这个8bit的编号作为颜色值,绘制到屏幕的相应位置<br>    5. 正确处理完24bit bmp中的每一个像素,就ok了<br><br>    这实际上就是将24bit色bmp转换为256色bmp的一种简单算法,效果也不错,原理也很简单。选择最佳匹配色也很容易,就是选泽颜色空间中,距离最小的,距离函数直接使用欧式距离就非常理想。这个算法是我自己独立思考出来的,可以说是原创。<br><br>        RockCarry<br>        2007-2-12<br><br><br>
[align=right][color=#000066][此贴子已经被作者于2007-2-12 11:43:36编辑过][/color][/align]

ba_wang_mao 发表于 2007-2-13 08:32

谢谢 RockCarry,我试试<BR>

页: [1]

Powered by Discuz! Archiver 6.1.0  © 2001-2007 Comsenz Inc.