请给我一个在DOS下显示BMP位图的C语言源程序

Epson 2000-02-23 04:05:00
...全文
498 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
Kevin_qing 2000-08-18
  • 打赏
  • 举报
回复
给我你的mail
发一個读所有非压缩BMP格式,支持真彩显示的源程序
lanfeng 2000-08-18
  • 打赏
  • 举报
回复
Epson:
Dos 下显示bmp图像相当复杂,其中大致:
1.RLE4压缩算法。
2.RLE8压缩算法.
3.单色.真彩色.不压缩.(BGR)
4.图像数据从左下角开是始向文件写入。
5.由于DOS只有16色,256色以上的图形需参考VGA自行编写显示模块,并非调色板能解决的。
我手上没源代码,只有相关资料复印件如你在武汉可于我联系:95829-52569
或查看:<<现代流行图像文件格式>>一书。(不记得谁写的,哪个出版社了)
eclipse 2000-07-25
  • 打赏
  • 举报
回复
前面几个程序好象都有问题。
另外,调色板到底是什么东西。怎么用?
满桌烟灰 2000-07-10
  • 打赏
  • 举报
回复
显示BMP图形很简单,但是你得说明需要什么环境下的显示程序,特定的显示卡?还是通用的VESA(VBE)?显示分辨率是多少?显示颜色数是多少?
bluewater 2000-07-09
  • 打赏
  • 举报
回复
对不起,上个贴子发错了~~~~

重新来过!

1 BMP图形的存储格式
0-1文件类型标志,一般为字符"BM"的ASCII码.
2-5一个由低字节向高字节排放的二进制数,表示该BMP文件的长度.
10-13一个由低字节向高字节排放的二进制数,表示图象数据的起始位置,也可以
理解为文件描述头的长度(单位为字节)
18-19一个由低字节向高字节排放的二进制数,表示图象的宽度.
22-23一个由低字节向高字节排放的二进制数,表示图象的高度.
28每象素所占的位数
48调色板中的颜色数
54~ 从这里开始为调色板(B,G,R,RES)
图象数据

注意:图象的实际宽度width在第18-19字节给出,但读取图象数据时应注意,当width
不是8的整数倍时,应将width'=(width/8+1)*8,即两行图象数数之间的间隔不是width
而是width'.
调色板的颜色数与图象数据的起始位置,每象素所占的位数是相关的.
调节器色板中每四个字节表示一个颜色,分别给出B,G,R,RES分量,所以调色板的
大小=颜色数*四个字节.
图象区存放的数据是象素颜色在调色板中的序号,值得指出的是存取时象素的
排列是自左而右,从上而下的.

2 象素显示
象素显示即是如何反调色板写到显示卡上去并反象素显示出来.
对于是6色可以用C语言提供的VGA16色驱动程简单地完成显示.需要指出的是对于
16色图形,图象数据与VGA16色所设定的颜色之间有一转换关系,即红与蓝两色分量交
换位置.例如BMP中的1指的是VBA16色的4号颜色.

BMP中的数据值 实际VGA16色中的颜色序号
1 4
3 6
4 1
6 3
9 C
B E
C 9
E B

下面给出程序:

bmp.c

#include <stdio.h>
#include <math.h>
#include <alloc.h>
#include <io.h>
#include <dos.h>
#include <mem.h>
#include <conio.h>
#include <stdlib.h>
unsigned int im_width,pat_size;
main(argc,argv)
int argc;
char *argv[];
{
unsigned char buffer[54];
unsigned char pat[256][4];
int bit_count;
long i;
unsigned char huge *img1;
unsigned char huge *img;
unsigned int width,higth,j,k,color;
FILE *fp1,*fp2;
union {
struct {
unsigned lobyte:4;
unsigned hibyte:4;
}parts;
struct {
unsigned char allbyte;

}whole;

}db1;
if(argc<2)
{
printf("Usage:bmp bmpfilename\n");
exit(1);
}
if(!(fp1=fopen(argv[1],"rb")))
{
printf("Open file %s error!\n",argv[1]);
exit(1);
}
fread(buffer,1,54,fp1);
im_width=buffer[19]*256+buffer[18];
higth=buffer[23]*256+buffer[22];
if((im_width%8)!=0)
width=(im_width/8+1)*8;
else width=im_width;
pat_size=(buffer[11]*256+buffer[10]-54)/4;
bit_count=buffer[28];
/* read color pattern fread(pat,sizeof(unsigned char ),pat_size*4,fp1); */
if(!(img=farcalloc((width/(8/bit-count)),sizeof(unsigned char))))
{
printf("Can't open pointor img.\n");
abort();
}
{
if(bit_count==4)
for(k=0;k<higth;k++)
fread(img,sizeof(unsigned char),(width/2),fp1);
for(j=0;j<width/2;j++){
db1.whole.allbyte=(*)img+j));
(*(img1+(long)(higth-1-k)*(long)width+(long)j*2))=db1.parts.hibyte;
(*(img1+(long)(higth-1-k)*(long)width+(long)j*2+11))=db1.parts.lobyte;
}
}
else /*bit _count==8
for(k=0;k<higth;k++) {
fread(img,sizeof(unsigned char),width,fp1);
for(j=0;j<width;j++)
(*(img1+(long)(higth-1-k)*(long)width+(long)j))=(*(img+j));
}
disp(img1,pat,higth,width);
fclose(fp1);
farfree(img);
farfree(img1);
}
}


#define SCREEN_HIGHT 200
#define SCREEN_WIDTH 320
#define MMODE 0x13
disp(unsigned char huge *image,unsigned char *pattern,unsigned int row,unsigned int column)
{
unsigned char far *im;
unsigned char far *buf;
unsigned char pat[256][3];
unsigned int column1,x0=0,y0=0;
int i,j;
long size;
void set_color_pat(unsigned char far pat[256][3]);
void set_mode(int);
if(row-x0)>SCREEN_HIGHT) row=SCREEN_HIGHT;
else row=row-x0;
if(im_width-y0>SCREEN_WIDTH) column1=SCREEN_WIDTH;
else column1=im-width-y0;
set_mode(MMODE);
/* change value of red and blue */
for(i=0;i<pat_size;i++)
for(j=0;j<3;j++)
pati][j]=(*(pattern+i*4+(2-j)))/4;
set_color_pat(pat);
/* write to display card */
buf=(unsigned char far *)MK_FP(oxa000,0);
lsize=0;
for(i=0;i<row;i++)
{
lsize=lsize+SCREEN_WIDTH;
if(lsize<655361)
{
memcpy(buf,(image+i*column),column1);
buf=buf+SCREEN-WIDTH;
}
else
{ pritf("overflow:image too large.\n");
}
}
getch();
set_mode(3);
}
void set_mode(int mode)
{ union REGS r;
r.h.ah=0;
r.h.al=mode;
int86(0x10,&r,&r);
}

void set_color_pat(unsigned char far pat[256][3])
{
union REGS r;
struct SREGS s;
r.h.ah=0x10;
r.h.al=0x12;
r.x.bx=0;
r.x.cx=256;
r.x.dx=FP_OFF(pat);
s.es=FP_SEG(pat);
int86x(0x10,&r,&r,&s);
}



bluewater 2000-07-09
  • 打赏
  • 举报
回复
1 BMP图形的存储格式
0-1文件类型标志,一般为字符"BM"的ASCII码.
2-5一个由低字节向高字节排放的二进制数,表示该BMP文件的长度.
10-13一个由低字节向高字节排放的二进制数,表示图象数据的起始位置,也可以
理解为文件描述头的长度(单位为字节)
18-19一个由低字节向高字节排放的二进制数,表示图象的宽度.
22-23一个由低字节向高字节排放的二进制数,表示图象的高度.
28每象素所占的位数
48调色板中的颜色数
54~ 从这里开始为调色板(B,G,R,RES)
图象数据

注意:图象的实际宽度width在第18-19字节给出,但读取图象数据时应注意,当width
不是8的整数倍时,应将width'=(width/8+1)*8,即两行图象数数之间的间隔不是width
而是width'.
调色板的颜色数与图象数据的起始位置,每象素所占的位数是相关的.
调节器色板中每四个字节表示一个颜色,分别给出B,G,R,RES分量,所以调色板的
大小=颜色数*四个字节.
图象区存放的数据是象素颜色在调色板中的序号,值得指出的是存取时象素的
排列是自左而右,从上而下的.

2 象素显示
象素显示即是如何反调色板写到显示卡上去并反象素显示出来.
对于是6色可以用C语言提供的VGA16色驱动程简单地完成显示.需要指出的是对于
16色图形,图象数据与VGA16色所设定的颜色之间有一转换关系,即红与蓝两色分量交
换位置.例如BMP中的1指的是VBA16色的4号颜色.

BMP中的数据值 实际VGA16色中的颜色序号
1 4
3 6
4 1
6 3
9 C
B E
C 9
E B

下面给出程序:

bmp.c

#include <stdio.h>
#include <math.h>
#include <alloc.h>
#include <io.h>
#include <dos.h>
#include <mem.h>
#include <conio.h>
unsigned char pat[256][4];
int bit_count;
long i;
unsigned char huge *img1;
unsigned char huge *img;
unsigned int width,higth,j,k,color;
FILE *fp1,*fp2;
union {
struct {
unsigned lobyte:4;
unsigned hibyte:4;
}parts;
struct {
unsigned char allbyte;

}whole;

}db1;
if(argc<2)
{
printf("Usage:bmp bmpfilename\n");
exit(1);
}
if(!(fp1=fopen(argv[1],"rb")))
{
printf("Open file %s error!\n",argv[1]);
exit(1);
}
fread(buffer,1,54,fp1);
im_width=buffer[19]*256+buffer[18];
higth=buffer[23]*256+buffer[22];
if((im_width%8)!=0)
width=(im_width/8+1)*8;
else width=im_width;
pat_size=(buffer[11]*256+buffer[10]-54)/4;
bit_count=buffer[28];
/* read color pattern fread(pat,sizeof(unsigned char ),pat_size*4,fp1); */
if(!(img=farcalloc((width/(8/bit-count)),sizeof(unsigned char))))
{
printf("Can't open pointor img.\n");
abort();
}
{
if(bit_count==4)
for(k=0;k<higth;k++)
fread(img,sizeof(unsigned char),(width/2),fp1);
for(j=0;j<width/2;j++){
db1.whole.allbyte=(*)img+j));
(*(img1+(long)(higth-1-k)*(long)width+(long)j*2))=db1.parts.hibyte;
(*(img1+(long)(higth-1-k)*(long)width+(long)j*2+11))=db1.parts.lobyte;
}
}
else /*bit _count==8
for(k=0;k<higth;k++) {
fread(img,sizeof(unsigned char),width,fp1);
for(j=0;j<width;j++)
(*(img1+(long)(higth-1-k)*(long)width+(long)j))=(*(img+j));
}
disp(img1,pat,higth,width);
fclose(fp1);
farfree(img);
farfree(img1);
}
}


#define SCREEN_HIGHT 200
#define SCREEN_WIDTH 320
#define MMODE 0x13
disp(unsigned char huge *image,unsigned char *pattern,unsigned int row,unsigned int column)
{
unsigned char far *im;
unsigned char far *buf;
unsigned char pat[256][3];
unsigned int column1,x0=0,y0=0;
int i,j;
long size;
void set_color_pat(unsigned char far pat[256][3]);
void set_mode(int);
if(row-x0)>SCREEN_HIGHT) row=SCREEN_HIGHT;
else row=row-x0;
if(im_width-y0>SCREEN_WIDTH) column1=SCREEN_WIDTH;
else column1=im-width-y0;
set_mode(MMODE);
/* change value of red and blue */
for(i=0;i<pat_size;i++)
for(j=0;j<3;j++)
pati][j]=(*(pattern+i*4+(2-j)))/4;
set_color_pat(pat);
/* write to display card */
buf=(unsigned char far *)MK_FP(oxa000,0);
lsize=0;
for(i=0;i<row;i++)
{
lsize=lsize+SCREEN_WIDTH;
if(lsize<655361)
{
memcpy(buf,(image+i*column),column1);
buf=buf+SCREEN-WIDTH;
}
else
{ pritf("overflow:image too large.\n");
}
}
getch();
set_mode(3);
}
void set_mode(int mode)
{ union REGS r;
r.h.ah=0;
r.h.al=mode;
int86(0x10,&r,&r);
}

void set_color_pat(unsigned char far pat[256][3])
{
union REGS r;
struct SREGS s;
r.h.ah=0x10;
r.h.al=0x12;
r.x.bx=0;
r.x.cx=256;
r.x.dx=FP_OFF(pat);
s.es=FP_SEG(pat);
int86x(0x10,&r,&r,&s);
}
flyingknight 2000-05-29
  • 打赏
  • 举报
回复
我有一个在watcom c++,asm下开发的DOS4GW保护模式下的真彩色,高彩色bmp显示程序,还包括一套自己做的
MFC for DOS4GW库...如果你要的话,我可以给你发一份
OICQ:1094294, ICQ:17910213, EMAIL:hongbo.yu@263.net
玫瑰骑士
flyingknight 2000-05-29
  • 打赏
  • 举报
回复
我有一个在watcom c++,asm下开发的DOS4GW保护模式下的真彩色,高彩色bmp显示程序,还包括一套自己做的
MFC for DOS4GW库...如果你要的话,我可以给你发一份
halfdream 2000-05-26
  • 打赏
  • 举报
回复
Epson ,那显示不正常的现象是什么? 可能是因为那种BMP格式不同吧。
有的BMP 使用的RLE压缩算法的,处理起来要麻烦一些。
我以前也写过显示BMP和PCX图这样的程序, 也把它改写成LINUX 下的程序。
可惜不知道扔到我硬盘上哪个角落去了。
yongdu 2000-05-25
  • 打赏
  • 举报
回复
我有TC2.0下通过的源代码
li_z 2000-05-25
  • 打赏
  • 举报
回复
UNIX下的可以吗?
Philip 2000-02-25
  • 打赏
  • 举报
回复
我有源代码,可以支持任何位数的BMP,要否?
Epson 2000-02-25
  • 打赏
  • 举报
回复
上一个网友贴的在我的机器上显示不正常,我不知道是为什么,如果你要使有不同的版本
我想要一份。我的编译环境是Borland C 3.1 for DOS.
forgettor 2000-02-23
  • 打赏
  • 举报
回复
这有一个BC3.1下显示256色bmp位图的程序

#include <dos.h>
#include <alloc.h>
#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <process.h>

typedef struct
{
unsigned char rgbBlue;
unsigned char rgbGreen;
unsigned char rgbRed;
unsigned char rgbReserved;
}RGBQUAD;

RGBQUAD rgb;

char palette[48];

void Point(int x,int y,int color)
{
unsigned char register mask=0x80;
char far *p;
char far *base=(char far *)0xa0000000;

p=base+y*80+x/8;
mask>>=x%8;
asm{
mov dx,3ceh
xor al,al
out dx,al
inc dx
mov al,byte ptr color
out dx,al

dec dx
mov al,1
out dx,al
inc dx
mov al,0ffh
out dx,al

dec dx
mov al,8
out dx,al
inc dx
mov al,mask
out dx,al
}
*p&=0xff;
}

void set_palette(FILE *fp)
{
char i;

fseek(fp,0x36,SEEK_SET);
outportb(0x3c8,0);
for(i=0;i<16;i++)
{
fread(&rgb,sizeof(RGBQUAD),1,fp);
if(i==6)outportb(0x3c8,20);
if(i==7)outportb(0x3c8,7);
if(i==8)outportb(0x3c8,56);
outportb(0x3c9,rgb.rgbRed>>2);
outportb(0x3c9,rgb.rgbGreen>>2);
outportb(0x3c9,rgb.rgbBlue>>2);

palette[i*3+0]=rgb.rgbRed>>2;
palette[i*3+1]=rgb.rgbGreen>>2;
palette[i*3+2]=rgb.rgbBlue>>2;
}
}

void display_bmp(FILE *fp)
{
unsigned char color=0;
int i,j;
unsigned char *image;

image=(unsigned char *)malloc(38400);

_AH=0;_AL=0x12;
geninterrupt(0x10);

set_palette(fp);

// _AX=0x1201;_BL=0x36;
// geninterrupt(0x10);

fseek(fp,118,SEEK_SET);
for(j=480;j>0;j--)
{
for(i=0;i<640;i++)
{
color=fgetc(fp);
Point(i++,j,(color&0xf0)>>4);
if(i<640)
Point(i,j,color&0x0f);
}
}
getch();

FILE *fp1=fopen("gl.img","wb");

fwrite(palette,48,1,fp1);
for(i=0;i<4;i++)
{
outportb(0x3ce,4);
outport(0x3cf,i);
memcpy(image,MK_FP(0xa000,0),38400);
fwrite(image,38400,1,fp1);
}

// _AX=0x1200;_BL=0x36;
// geninterrupt(0x10);

_AH=0;_AL=0x03;
geninterrupt(0x10);

fclose(fp);
fclose(fp1);
free(image);

}

void main()
{
FILE *fp;

fp=fopen("gl.bmp","rb");
if(!fp)
{
printf("<gl.bmp> isn't exist!\n");
exit(1);
}

display_bmp(fp);

}


69,336

社区成员

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

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