| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 2883 人关注过本帖
标题:8位读BMP图片问题
只看楼主 加入收藏
pegliu
Rank: 1
等 级:新手上路
帖 子:8
专家分:0
注 册:2008-8-9
收藏
 问题点数:0 回复次数:7 
8位读BMP图片问题
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <math.h>
#include <fcntl.h>
#include <bios.h>
#include <dos.h>
#include <io.h>
#include <graphics.h>
int COLORS[16][3]=
{
        /* R   G   B        Index    ColorName        */
        {  0,  0,  0},     /* 00 Black                */
        {  0,  0,255},     /* 01 Blue                */
        {  0,128,  0},        /* 02 Green                */
        {  0,255,255},     /* 03 Cyan                */
        {255,  0,  0},     /* 04 Red                */
        {255,  0,255},     /* 05 Magenta            */
        {165, 42, 42},     /* 06 Brown                */
        {211,211,211},     /* 07 LightGray        */
        {169,169,169},     /* 08 DarkGray            */
        {173,216,230},     /* 09 LightBlue        */
        {144,238,144},     /* 10 LightGreen        */
        {144,238,238},        /* 11 LightCyan        */
        {238,144,144},     /* 12 LightRed            */
        {238,144,238},     /* 13 LightMegenta    */
        {255,255,  0},     /* 14 Yellow            */
        {255,255,255},        /* 15 White                */
};
typedef struct _tagBITMAPFILEHEADER{
  unsigned short WType;
  unsigned long  DSize;
  int WReserved1;
  unsigned short WReserved2;
  unsigned long  DOffBits;
}BITMAPFILEHEADER;

typedef struct _tagBITMAPINFOHEADER{
  unsigned long  DSize; //表示本结构的大小
  long  LWidth; //位图的宽度
  long  LHeight; //位图的高度
  unsigned short WPlanes; //永远为1 ,由于没有用过所以 没做研究 附msdn解释
                   //Specifies the number of planes for the target device. This value must be set to 1.
  unsigned short WBitCount;//位图的位数  分为1 4 8 16 24 32 本文没对1 4 进行研究
  unsigned long  DCompression; //本以为压缩类型,但是却另外有作用,稍候解释
  unsigned long  DSizeImage; //表示位图数据区域的大小以字节为单位
  long  LXPelsPerMeter;
  long  LYPelsPerMeter;
  unsigned long  DClrUsed;
  unsigned long  DClrImportant;
}BITMAPINFOHEADER;

typedef struct _tagRGBQUAD {
  unsigned char   rgbBlue;      //蓝色的亮度(值范围为0-255)
  unsigned char   rgbGreen;     //绿色的亮度(值范围为0-255)
  unsigned char   rgbRed;       //红色的亮度(值范围为0-255)
  unsigned char   rgbReserved;  //保留,必须为0
}RGBQUAD;

typedef struct _tagBITMAPINFO{
  BITMAPINFOHEADER  bmiHeader;
  RGBQUAD bmiColors;
}BITMAPINFO;

BITMAPFILEHEADER bmfh;
BITMAPINFO info;

int GetColor(unsigned int red,unsigned int green,unsigned int blue)
{
    int i,index=0;
    unsigned long dist,temp;
    temp=195075;
    for(i=0;i<15;i++)
    {
        dist=0;
        dist+=(COLORS[i][0]-red)*(COLORS[i][0]-red);
        dist+=(COLORS[i][1]-green)*(COLORS[i][1]-green);
        dist+=(COLORS[i][2]-blue)*(COLORS[i][2]-blue);
         /* minimum dist^2=2492, 623=[minimum dist^2]/4 */
        if(dist<=623)
            return i;
        if(dist<temp)
        {
            index=i;
            temp=dist;
        }
    }
    return index;
}
/* draw X and Y axes */
int main()
{
  int gd = DETECT;
  int gm = 0;
  int i;
  int j;
  int index;
  FILE *fp;
  long width;
  long height;
  int  pitch;
  RGBQUAD quad[256];
  unsigned char *buffer;
  unsigned char r,g,b;
  registerbgidriver(EGAVGA_driver);
  initgraph(&gd,&gm,"");
  cleardevice();
  fp = fopen("C:\\WINDOWS\\pix.bmp","r");
  if(fp == NULL)
  {
    printf("no file find!\n");
    return -1;
  }
  fread(&bmfh,sizeof(bmfh),1,fp);
  if(bmfh.WType!=0x4d42)
  {
    printf("this picture is not BMPfile!\n");
    return -1;
  }
  fread(&info.bmiHeader,sizeof(BITMAPINFOHEADER),1,fp);
  width  = info.bmiHeader.LWidth;
  height = info.bmiHeader.LHeight;
  buffer = malloc(info.bmiHeader.DSizeImage);
  fseek(fp,bmfh.DOffBits,0);
  fread(buffer,info.bmiHeader.DSizeImage,1,fp);
  if(width%4 == 0)
  {
    pitch = width;
  }
  else
  {
    pitch = width+4-width%4;
  }
  //width = (width * bmfh.DOffBits + 31) / 32 * 4;
  fseek(fp,bmfh.DOffBits-sizeof(RGBQUAD)*256,0);
  fread(quad,sizeof(RGBQUAD)*256,1,fp);
  if(height>0)
  {
    for(i=0;i<height;i++)
    {
      for(j=0;j<width;j++)
      {
        index = buffer[i*pitch+j];
        r     = quad[index].rgbRed;
        g     = quad[index].rgbGreen;
        b     = quad[index].rgbBlue;
        putpixel(220+i,140+j,GetColor(r,g,b));//RGB(r,g,b));

      }
    }
  }
  else
    for(i=0;i<0-height;i++)
    {
       for(j=0;j<width;j++)
       {
          index = buffer[i*pitch+j];
          r     = quad[index].rgbRed;
          g     = quad[index].rgbGreen;
          b     = quad[index].rgbBlue;
          putpixel(220+i,140+j,GetColor(r,g,b));//RGB(r,g,b));
       }
    }

  getch();
  closegraph();
  return 0;
}

显示图片出错.
搜索更多相关主题的帖子: include BMP Green Cyan math 
2008-08-09 13:42
pegliu
Rank: 1
等 级:新手上路
帖 子:8
专家分:0
注 册:2008-8-9
收藏
得分:0 
跪求大家给我一个可以显示256色的代码  用C写的.能在TC2.0下编译通过
2008-08-09 14:53
pegliu
Rank: 1
等 级:新手上路
帖 子:8
专家分:0
注 册:2008-8-9
收藏
得分:0 
我的邮箱是pegliu@
2008-08-09 19:41
扫门星
Rank: 1
等 级:新手上路
帖 子:20
专家分:0
注 册:2008-8-7
收藏
得分:0 
又是颜色输出的问题
关于TC对点颜色输出:putpixel(220+i,140+j,GetColor(r,g,b));//RGB(r,g,b));
你要明白一个真理,只要你是纯TC对点输出putpixel(x,y,Color);中的Color值等于你给的值除以15以后的余值。
一句话就是:Color的值只能是 0至15 。
如果你真想玩256色的输出,那你就下载《NEO SDK 图形库》按说明做好后,你的TC就可以输出你想要的256色了。
2008-08-09 20:13
hoodlum1980
Rank: 2
来 自:浙江大学
等 级:论坛游民
威 望:2
帖 子:289
专家分:23
注 册:2008-2-24
收藏
得分:0 
你好像引用了我写的代码。
2008-08-09 23:11
pegliu
Rank: 1
等 级:新手上路
帖 子:8
专家分:0
注 册:2008-8-9
收藏
得分:0 
呵呵,正在学,有一部分是网上的,呵呵
2008-08-10 14:25
hoodlum1980
Rank: 2
来 自:浙江大学
等 级:论坛游民
威 望:2
帖 子:289
专家分:23
注 册:2008-2-24
收藏
得分:0 
[bo][un]pegliu[/un] 在 2008-8-10 14:25 的发言:[/bo]

呵呵,正在学,有一部分是网上的,呵呵


我看你的代码应该是基本上引用的我很久前贴的一个例子。我已经把那个例子改写为了一个头文件的形式,并把图片资源应用到我以前写的“连连看”程序,可以丰富游戏的界面,你可以参考下:

https://bbs.bccn.net/thread-230193-1-3.html

在这个帖子附近我还发了一个图片时钟的范例:

https://bbs.bccn.net/thread-230374-1-3.html

另外一点,针对上面的回复是正确的,我在这里使用的是把真彩色图片“降色”为16色了,以能够在TC的绘图模式下显示。

这样做的好处是,绝不仅仅是展示静态的图片,还要把展示图片用比较高效的方式结合到你的游戏中(游戏对更新速度要求较高),比如在图片时钟的例子中用数字显示的那个时间就是每秒钟更新贴图来实现的,你能够依然使用graphics.h里面的其他绘图函数。同时这个头文件中,我需要一些内存来存储像素颜色,因此64K的内存限制也限制了我们能加载的位图的大小。这体现在你用原来的范例,不需要考虑位图的尺寸,但使用这个头文件,你能加载的位图将有像素数量限制。

[[it] 本帖最后由 hoodlum1980 于 2008-9-1 20:06 编辑 [/it]]
2008-09-01 20:04
hoodlum1980
Rank: 2
来 自:浙江大学
等 级:论坛游民
威 望:2
帖 子:289
专家分:23
注 册:2008-2-24
收藏
得分:0 
楼主我发现我以前的代码中的GetColor方法存在一个逻辑错误,会导致返回color时返回错误值,
正确的方法应该如下:(注意特殊颜色的部分,错误的代码把这两部分的顺序搞颠倒了。。。。)
--------------------------------------------------------------------------------------------------
/*根据RGB颜色,获取最相近的VGA模式颜色!*/
unsigned char GetNearestColor(unsigned int red,unsigned int green,unsigned int blue)
{
    unsigned char i,index=0;
    unsigned long dist,temp;
    temp=195075;
    for(i=0; i<[bo]16[/bo]; i++)   /*for中间的语句应是i<16,而不是i<15*/
    {
        dist=0;
        dist+=(BMCOLORS[i][0]-red)*(BMCOLORS[i][0]-red);
        dist+=(BMCOLORS[i][1]-green)*(BMCOLORS[i][1]-green);
        dist+=(BMCOLORS[i][2]-blue)*(BMCOLORS[i][2]-blue);

        [bo][it]/* 原来的代码把以下两块的顺序写错,导致逻辑错误!!! */[/it][/bo]
        [bo]if(dist<temp)
        {
            index=i;
            temp=dist;
        }[/bo]
    

        /* minimum dist^2=2491,623=2491/4 */    
            [bo]if(temp<623)
            return i;[/bo]  
    
    }
    return index;
}
-------------------------------------------------------------------------------------


我已经更正了这个错误,请下载这个附件,里面包含最新的头文件:

http://bbs.bccn.net/attachment.php?aid=36793&k=88eea4e305389940431bf113d631c3de&t=1220368248

修正该错误以后的图片时钟的运行截图:

[[it] 本帖最后由 hoodlum1980 于 2008-9-2 23:11 编辑 [/it]]

IMGCLOCK.gif (13.55 KB)
图片附件: 游客没有浏览图片的权限,请 登录注册
2008-09-02 21:36
快速回复:8位读BMP图片问题
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.018525 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved