 |
你可以在http://www.wotsit.org/找到所有图形文件的格式的介绍。你也可以访问PaintLib的主页http://www.paintlib.de/paintlib/。Paintlib是一个C++类,支持PNG、TGA、TIFF、JPEG/JFIF、Windows BMP、Mac PICT和EPS。不过这是个针对Windows的类,你在DOS下需要修改显示部分。另外,你可以参考郑全战等的《图象格式编程指南》一书(清华大学出版社,ISBN 7-302-01436-1),这本书详细介绍常用的图象格式,而且是针对DOS的,挺适合你的。另外,也可以参考:《最流行图像格式实用参考手册》。
lamcitiz的意见:
这有一个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);
}
---------------
bluewater:
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);
}
更多好看清訪問:http://www.156ok.com/
相关问题:
QA000398 "如何在VB中编程使.bmp文件转换为.gif或.jpg文件"
QA000546 "如何在VC6中显示JPG图象"
QA001526 "VB中如何.bmp文件转换为.jpg文件"
此问题由李海回答。
附加关键字:编程, 源程序, programming, source code, C/C++, MFC, C++ Builder, Borland C++, Turbo C, C, BCB, 图形、图象, picture, graph, image, draw。
|