如何在TC中显示BMP位图?

xunqinji 2004-11-21 05:24:31
如何在TC中显示BMP位图?
怎样在TC中构建bmp位图结构体?
请各位高手指点哦.
...全文
200 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
hj5182001 2004-12-12
  • 打赏
  • 举报
回复
ding
xunqinji 2004-12-11
  • 打赏
  • 举报
回复
谢谢!
我前几天用一个非常简单的方法写了一个函数:
在这个函数里我是通过直接写屏的方法实现位图(bmp 格式位图),但是只能显示黑白2色,我当时我不明白,位图文件的全部信息都已经写入显存里,为什么还不能显示,幸亏现在得到高手的指点,终于明白了一点点。
coyprightbao 2004-11-22
  • 打赏
  • 举报
回复
高手云集!
superman421 2004-11-21
  • 打赏
  • 举报
回复
着是个简单的例子,显示固定大小的256色图片
各个函数可以自己改进,这里只是示例
#include<stdio.h>
#include<dos.h>
#include<stdlib.h>

#define VGA256 0x13
#define TEXT_MODE 0x03

#define PALETTE_MASK 0x3c6
#define PALETTE_RD 0x3c7
#define PALETTE_WR 0x3c8
#define PALETTE_DATA 0x3c9

#define X 140
#define Y 140


typedef struct BMP_file
{
unsigned int bfType;
unsigned long bfSize;
unsigned int Reserved1;
unsigned int reserved2;
unsigned long bfOffset;
}bitmapfile;

typedef struct BMP_info
{
unsigned long biSize;
unsigned long biWidth;
unsigned long biHeight;
unsigned int biPlanes;
unsigned int biBitCount;
unsigned long biCompression;
unsigned long biSizeImage;
unsigned long biXpolsPerMeter;
unsigned long biYpelsPerMeter;
unsigned long biClrUsed;
unsigned long biClrImportant;
}bitmapinfo;


typedef struct RGB_BMP_typ
{
unsigned char blue;
unsigned char green;
unsigned char red;
unsigned char reserved;
}RGB_BMP;

typedef struct bmp_picture_typ
{
bitmapfile file;
bitmapinfo info;
RGB_BMP palette[256];
} bmp_picture;

void setVideoMode(int);
void loadFile();
void setPalette();
void showImage(int x,int y,char* input);

bmp_picture bmpPicture;
char input[X*Y],output[X*Y],fileName[15];
unsigned char far *videoBuffer=(char far*)0xA0000000L;

main()
{
int i,x,y;
char key;
loadFile();
setVideoMode(VGA256);
loadFile();
setPalette();
showImage(0,0,input);
getch();
setVideoMode(TEXT_MODE);
}

void setVideoMode(int mode)
{
union REGS inregs,outregs;
inregs.h.ah=0;
inregs.h.al=(unsigned char)mode;
int86(0x10,&inregs,&outregs);
}

void loadFile()
{
int i;
FILE *bmp;
if((bmp=fopen("test.bmp","rb"))==NULL)
{
printf("File not found!");
getch();
exit(0);
}
else{
fread(&bmpPicture.file,sizeof(bitmapfile),1,bmp);
fread(&bmpPicture.info,sizeof(bitmapinfo),1,bmp);
for(i=0;i<256;i++)
fread(&bmpPicture.palette[i],sizeof(RGB_BMP),1,bmp);
for(i=0;i<X*Y;i++)
fread(&input[i],1,1,bmp);
}
fclose(bmp);
}

void setPalette()
{
int i;
outp(PALETTE_MASK,0xff);
for(i=0;i<256;i++)
{
outp(PALETTE_WR,i);
outp(PALETTE_DATA,bmpPicture.palette[i].red/4);
outp(PALETTE_DATA,bmpPicture.palette[i].green/4);
outp(PALETTE_DATA,bmpPicture.palette[i].blue/4);
}
}

void showImage(int x,int y,char *input)
{
int xx,yy;
for(xx=0;xx<X;xx++)
for(yy=0;yy<Y;yy++)
videoBuffer[320*(X-1-xx+x)+yy+y]=input[X*xx+yy];
}
milozy1983 2004-11-21
  • 打赏
  • 举报
回复
/*--------------------256bmp.c----------------------*/
#include "dos.h"
#include "stdio.h"
#include "process.h"
#include "bios.h"
#include "math.h"

unsigned char set_SVGA_mode(int vmode) /*设置SVGA屏幕模式*/
{
union REGS r;
r.x.ax=0x4f02;
r.x.bx=vmode;
int86(0x10,&r,&r);
return(r.h.ah);
}
unsigned int get_SVGA_mode() /*获取当前SVGA屏幕模式*/
{
union REGS r;
r.x.ax=0x4f03;
int86(0x10,&r,&r);
return(r.x.bx);
}
void put_bmp(int x,int y,char *name)
{
char buffer[640],page_new=0,page_old=0;
int i,j,k,n,r,g,b;
long position,width,length;
FILE *fp;
strcpy(buffer,name);
fp=fopen(buffer,"rb");
fseek(fp,28,SEEK_SET);
fread(&i,2,1,fp);
fseek(fp,18,SEEK_SET);
fread(&width,4,1,fp);/*得到图片的长度和宽度*/
fread(&length,4,1,fp);
fseek(fp,54,SEEK_SET);
for(i=0;i<256;i++) /*按照该图片的DAC色表设置色彩寄存器*/
{
b=fgetc(fp);
g=fgetc(fp);
r=fgetc(fp); /*获取R、G、B分量*/
outportb(968u,i);
outportb(969u,r>>2);
outportb(969u,g>>2);
outportb(969u,b>>2);
fgetc(fp);
}
k=(width%4)?(4-width%4):0; /*宽度修正值*/
for(j=length-1;j>=0;j--)
{
fread(buffer,width,1,fp);
for(i=0,n=0;i<width;i++,n++)
{
position=(j+y)*640l+i+x; /*计算要显示点的显存位置*/
page_new=position/65536l; /*计算显示页*/
if(page_new!=page_old) /*当显示页不同时更换页面,提高一定的输出速度*/
{
union REGS r;
r.x.ax=0x4f05;
r.x.bx=0;
r.x.dx=page_new; /*选择页面*/
int86(0x10,&r,&r);
page_old=page_new;
}
pokeb(0xa000,position%65536l,buffer[n]); /*写到显存位置*/
}
fseek(fp,k,SEEK_CUR); /*每行绘制完后修正宽度*/
}
fclose(fp);
}

void get_image(int x1,int y1,int x2,int y2,char *buffer)
{
int i,j,page_old=0,page_new=0;
FILE *fp;
char far *video=(char far *)0xA0000000L;
fp=fopen(buffer,"wb");
for(i=y1;i<=y2;i++)
for(j=x1;j<=x2;j++)
{
page_new=(640*i+j)/65536l; /*计算显示页*/
if(page_new!=page_old) /*当显示页不同时更换页面,提高一定的输出速度*/
{
union REGS r;
r.x.ax=0x4f05;
r.x.bx=0;
r.x.dx=page_new; /*选择页面*/
int86(0x10,&r,&r);
page_old=page_new;
}
fwrite(video+(640*i+j)%65536,1,1,fp);
}
fclose(fp);
}

void put_image(int x1,int y1,int x2,int y2,char *buffer)
{
int i,j,page_old=0,page_new=0;
FILE *fp;
char far *video=(char far *)0xA0000000L;
fp=fopen(buffer,"rb");
fseek(fp,0,SEEK_SET);
for(i=y1;i<=y2;i++)
for(j=x1;j<=x2;j++)
{
page_new=(640*i+j)/65536l; /*计算显示页*/
if(page_new!=page_old) /*当显示页不同时更换页面,提高一定的输出速度*/
{
union REGS r;
r.x.ax=0x4f05;
r.x.bx=0;
r.x.dx=page_new; /*选择页面*/
int86(0x10,&r,&r);
page_old=page_new;
}
fread(video+(640*i+j)%65536,1,1,fp);
}
fclose(fp);
}

main()
{
int savemode;
savemode=get_SVGA_mode(); /*先保存原来的屏幕模式*/
set_SVGA_mode(0x101); /*硬件无关性初始化屏幕为640*480 256色模式*/
put_bmp(0,0,"image.bmp");
getch();
set_SVGA_mode(savemode); /*恢复屏幕*/
}
iam500jun 2004-11-21
  • 打赏
  • 举报
回复
#include "dos.h"
#include "stdio.h"
#include "process.h"
#include "bios.h"
char ega_colors[16]={0,1,2,3,4,5,20,7,56,57,58,59,60,61,62,63};

void selectpage(register char page) /*换页函数*/
{ union REGS r;
r.x.ax=0x4f05;
r.x.bx=0;
r.x.dx=page; /*选择页面*/
int86(0x10,&r,&r);
}
unsigned char set_SVGA_mode(int vmode) /*设置SVGA屏幕模式*/
{ union REGS r;
r.x.ax=0x4f02;
r.x.bx=vmode;
int86(0x10,&r,&r);
return(r.h.ah);
}
unsigned int get_SVGA_mode() /*获取当前SVGA屏幕模式*/
{ union REGS r;
r.x.ax=0x4f03;
int86(0x10,&r,&r);
return(r.x.bx);
}
void main()
{ char buffer[640],page_new=0,page_old=0;
int i,j,k,n,r,g,b,savemode;
long position,width,length;
FILE *fp;
puts("This is a 256 color bmp viewer! Author:WuJin");
puts("Input filename:"); /*输入要显示的BMP文件路径*/
gets(buffer);
if((fp=fopen(buffer,"rb"))==NULL)
{ printf("Can't open file: %s",buffer);
return;
}
fseek(fp,28,SEEK_SET);
fread(&i,2,1,fp);
if(i!=8) /*检查是否为256色位图*/
{ puts("Not a 256 color bitmap!");
fclose(fp);exit(0);
}
fseek(fp,18,SEEK_SET);
fread(&width,4,1,fp);
fread(&length,4,1,fp);
savemode=get_SVGA_mode(); /*先保存原来的屏幕模式*/
set_SVGA_mode(0x101); /*硬件无关性初始化屏幕为640*480 256色模式*/
fseek(fp,54,SEEK_SET);
for(i=0;i<256;i++) /*按照该图片的DAC色表设置色彩寄存器*/
{ b=fgetc(fp);g=fgetc(fp);r=fgetc(fp); /*获取R、G、B分量*/
outportb(968u,i);
outportb(969u,r>>2);
outportb(969u,g>>2);
outportb(969u,b>>2);
fgetc(fp);
}
k=(width%4)?(4-width%4):0; /*宽度修正值*/
for(j=length-1;j>=0;j--)
{ fread(buffer,width,1,fp);
for(i=0,n=0;i<width;i++,n++)
{ position=j*640l+i; /*计算要显示点的显存位置*/
page_new=position/65536l; /*计算显示页*/
if(page_new!=page_old) /*当显示页不同时更换页面,提高一定的输出速度*/
{selectpage(page_new);page_old=page_new;}
pokeb(0xa000,position%65536l,buffer[n]); /*写到显存位置*/
}
fseek(fp,k,SEEK_CUR); /*每行绘制完后修正宽度*/
}
fclose(fp);
bioskey(0);
set_SVGA_mode(savemode); /*恢复屏幕*/
}


69,373

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧