![]() |
#2
SnowAssassin2010-03-31 19:04
|
要有注释的,越详细越好
![]() |
#2
SnowAssassin2010-03-31 19:04
分好几种呢,看看什么格式的,读取图形数据的方式不同。
|
![]() |
#3
SnowAssassin2010-03-31 19:05
还有显示的方式也不同,256色,与16色,8色,4色,2色,显示方式不同
|
![]() |
#4
SnowAssassin2010-03-31 19:12
这个是SVGA下的256色640×320模式下的读取BMP格式的函数,不同的格式,不同的位素,都不太同
#include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <dos.h> #include <process.h> #include <bios.h> /*文件头结构*/ typedef struct tagBITMAPFILEHEADER { int bfType; /* 通常是 'BM' 。现在来看似乎判断OS/2的标识已无什么意义*/ long bfSize; /* 文件大小,以字节为单位*/ int bfReserved1; /*保留,必须设置为0*/ int bfReserved2; /*保留,必须设置为0*/ long bfOffBits; /*从文件头开始到实际的图象数据之间的字节的偏移量。这*/ /*个参数是非常有用的,因为位图信息头和调色板的长度会*/ /*根据不同情况而变化,可以用这个偏移值迅速的从文件中*/ /*读取到位数据。 */ } BITMAPFILEHEADER; /*信息头结构*/ typedef struct tagBITMAPINFOHEADER { long biSize; /* 信息头大小 */ long biWidth; /* 图像宽度 */ long biHeight; /* 图像高度 */ int biPlanes; /* 必须为1 */ int biBitCount; /* 每像素位数,必须是1, 4, 8或24 */ long biCompression; /* 压缩方法 */ long biSizeImage; /* 实际图像大小,必须是4的倍数 */ long biXPelsPerMeter; /* 水平方向每米像素数 */ long biYPelsPerMeter; /* 垂直方向每米像素数*/ long biClrUsed; /* 所用颜色数*/ long biClrImportant; /* 重要的颜色数 */ } BITMAPINFOHEADER; /*调色板*/ typedef struct tagRGBQUAD { char rgbBlue; /*蓝色分量*/ char rgbGreen; /*绿色分量*/ char rgbRed; /*红色分量*/ char rgbReserved; } RGBQUAD; int COLS=640, ROWS=480; /* 缺省为256色640*480模式 */ /*换页函数*/ void selectpage(register char page) { union REGS r; r.x.ax=0x4f05; r.x.bx=0; r.x.dx=page; /*选择页面*/ int86(0x10,&r,&r); } /*设置SVGA屏幕模式*/ /*101H----256色640×480模式*/ /*103H----256色800×600模式*/ /*105H----256色1024×768模式*/ unsigned char set_SVGA_mode(int vmode) { union REGS r; r.x.ax=0x4f02; r.x.bx=vmode; int86(0x10,&r,&r); return(r.h.ah); } /*获取当前SVGA屏幕模式*/ unsigned int get_SVGA_mode() { union REGS r; r.x.ax=0x4f03; int86(0x10,&r,&r); return(r.x.bx); } /*设置调色板*/ void set_SVGA_palette(unsigned char r[], unsigned char g[], unsigned char b[]) { int k; for (k = 0; k < 256; k++) { outportb(0x03C8,k); outportb(0x03C9,r[k]>>2); outportb(0x03C9,g[k]>>2); outportb(0x03C9,b[k]>>2); } } void main() { BITMAPFILEHEADER FileHeader; BITMAPINFOHEADER bmiHeader; RGBQUAD bmiColors[256]; unsigned char buffer[1024], r[256], g[256], b[256]; unsigned int width, height, linebytes; long offset, position; char page_new=0,page_old=0; int i,j,k,n,savemode; FILE *fp; printf("Input filename:"); /*输入要显示的BMP文件路径*/ gets(buffer); if((fp=fopen(buffer,"rb"))==NULL) /*判断打开文件是否正确*/ { printf("Can't open file: %s",buffer); return; } if (fread((char *)&FileHeader, sizeof(FileHeader), 1, fp) != 1) { printf("Can't read file header !\n"); /* 读文件头 */ return; } if (FileHeader.bfType != 0X4D42) { /* BM */ fprintf(stderr, "Not a BMP file !\n"); return; } if (fread((char *)&bmiHeader, sizeof(bmiHeader), 1, fp) != 1) { fprintf(stderr, "Can't read bmiHeader !\n"); /* 读信息头 */ return; } if (bmiHeader.biBitCount > 8) { /* 不能显示真彩色图像 */ fprintf(stderr, "Can not display ture color image !\n"); return; } if (bmiHeader.biCompression != 0) { /* 不能处理压缩图像 */ fprintf(stderr, "Not non-compressed image !\n"); return; } width = (unsigned int)bmiHeader.biWidth; height = (unsigned int)bmiHeader.biHeight; linebytes = ((width*(long)bmiHeader.biBitCount+31)/32)*4; /* 每行字节数--4的整数倍 */ if (fread((char *)&bmiColors[0], 4, 256, fp) != 256) { /* 读调色板数据 */ fprintf(stderr, "Can't get palette !\n"); return; } savemode=get_SVGA_mode(); /*先保存原来的屏幕模式*/ set_SVGA_mode(0x101); /*硬件无关性初始化屏幕为256色640*480模式*/ COLS=640;ROWS=480; for (i = 0; i < 256; i++) { r[i] = bmiColors[i].rgbRed; g[i] = bmiColors[i].rgbGreen; b[i] = bmiColors[i].rgbBlue; } set_SVGA_palette(r, g, b); /* 设置调色板 */ offset = FileHeader.bfOffBits; fseek(fp, offset, SEEK_SET); /* 跳到位图数据的起始位置 */ for(j=height-1;j>=0;j--) { fread(buffer,linebytes,1,fp); for(i=0,n=0;i<width;i++,n++) { position=j*(long)COLS+i; /*计算要显示点的显存位置*/ page_new=position/65536l; /*计算显示页*/ if(page_new!=page_old) /*当显示页不同时更换页面,提高一定的输出速度*/ { selectpage(page_new); page_old=page_new; } pokeb(0xa000,position%65536l,buffer[n]); /*写到显存位置*/ } } fclose(fp); bioskey(0); set_SVGA_mode(savemode); /*恢复屏幕*/ } |
![]() |
#5
ba_wang_mao2010-04-08 09:27
这个是SVGA下的256色800×600模式下的读取BMP格式的函数,不同的格式,不同的位素,都不太同
#include <dos.h> #include <stdio.h> #include <mem.h> #include <alloc.h> #include <stdlib.h> #include <conio.h> #define VBE320X200X256 0X13 #define VBE640X480X256 0X101 #define VBE800X600X256 0X103 #define VBE1024X768X256 0X105 #define VARM_GRAPH_800(x,y) (((unsigned long)y<<9L)+((unsigned long)y<<8L)+((unsigned long)y<<5L)+((unsigned long)(x))) #define PALETTE_READ 0x3C7 /*VGA系统调色板读端口*/ #define PALETTE_WRITE 0x3C8 /*VGA系统调色板写端口*/ #define PALETTE_DATA 0x3C9 /*VGA系统调色板数据端口*/ #define makecol16(r,g,b) ((((unsigned int)(r)>>3)<<11) + (((unsigned int)(g)>>2)<<5) + ((b)>>3)) /*第一部分为位图文件头BITMAPFILEHEADER,其定义如下:*/ typedef struct tagBITMAPFILEHEADER { unsigned int bfType; /*指定文件类型,*.bmp文件的头两个字节都是"BM"*/ unsigned long bfSize; /*指定文件大小,包括这14个字节*/ unsigned int Reserved1; /*为保留字,不用考虑*/ unsigned int reserved2; /*为保留字,不用考虑*/ unsigned long bfOffset; /*为从文件头到实际的位图数据的偏移字节数,前三个部分的长度之和。*/ }BITMAPFILEHEADER; /*第二部分为位图信息头BITMAPINFOHEADER,这个结构的长度是固定的,为40个字节其定义如下:*/ typedef struct tagBITMAPINFOHEADER { unsigned long biSize; /*指定这个结构的长度,为40*/ unsigned long biWidth; /*指定图象的宽度,单位是象素*/ unsigned long biHeight; /*指定图象的高度,单位是象素*/ unsigned int biPlanes; /*必须是1,不用考虑*/ unsigned int biBitCount; /*指定表示颜色时要用到的位数,常用的值为1(黑白二色图),4(16色图),8(256色),24(真彩色图)*/ unsigned long biCompression; /*指定位图是否压缩,有效的值为BI_RGB,BI_RLE8,BI_RLE4,BI_BITFIELDS*/ unsigned long biSizeImage; /*指定实际的位图数据占用的字节数*/ unsigned long biXpolsPerMeter; /*指定目标设备的水平分辨率,单位是每米的象素个数。*/ unsigned long biYpelsPerMeter; /*指定目标设备的垂直分辨率,单位同上。*/ unsigned long biClrUsed; /*指定本图象实际用到的颜色数,如果该值为零,则用到的颜色数为2的biBitCount次方。*/ unsigned long biClrImportant; /*指定本图象中重要的颜色数,如果该值为零,则认为所有的颜色都是重要的。*/ }BITMAPINFOHEADER; typedef struct tagRGBQUAD /*用于读取调色板信息*/ { unsigned char Blue; unsigned char Green; unsigned char Red; unsigned char Reserved; }RGBQUAD; typedef struct tagRGB16M /* 16M RGB像素类型 */ { unsigned char Blue; unsigned char Green; unsigned char Red; }RGB16M; int g_cur_vbe_page = 0; ///////////////////////////////////////////////////////////////////////////////////////////////// // 图形模式初始化子程序 ///////////////////////////////////////////////////////////////////////////////////////////////// void _Cdecl InitGraph(void) { _AX = 0x4f02; _BX = VBE800X600X256; __int__(0x10); if(_AH != 0) { puts("Can't Initialize the graphics mode!"); exit(1); } } ///////////////////////////////////////////////////////////////////////////////////////////////// // 关闭图形模式,回到文本模式子程序 ///////////////////////////////////////////////////////////////////////////////////////////////// void _Cdecl CloseGraph(void) { _AX = 0x4f02; _BX = 0x03; __int__(0x10); } ///////////////////////////////////////////////////////////////////////////////////////////////// //显存换页函数 ///////////////////////////////////////////////////////////////////////////////////////////////// void _Cdecl set_vbe_page(int page) { if (g_cur_vbe_page != page) { _BX = 0; _DX = g_cur_vbe_page = page; _AX = 0x4F05; __int__(0x10); } } ///////////////////////////////////////////////////////////////////////////////////////////////// //设置单个调色板 ///////////////////////////////////////////////////////////////////////////////////////////////// void setpal(unsigned char i, unsigned char r, unsigned char g, unsigned char b) { outportb(PALETTE_WRITE,i); outportb(PALETTE_DATA,r); outportb(PALETTE_DATA,g); outportb(PALETTE_DATA,b); } void PutPixel16M(int x,int y,RGB16M color) { unsigned int RGB = makecol16(color.Red,color.Green,color.Blue); unsigned int page; char far *videoptr = (char far *)0xa0000000L; long addr = (long)y*2*800+(long)x*2; if (x >= 0 && x < 800 && y >= 0 && y < 600) { page = (int)(addr >> 16); set_vbe_page(page); *(videoptr + (unsigned int)(addr & 0xFFFF))= RGB & 0xFF; // RGB%256; *(videoptr + (unsigned int)(addr & 0xFFFF)+1)= RGB >> 0x08; // RGB/256; } } ///////////////////////////////////////////////////////////////////////////////////////////////// //画点函数 ///////////////////////////////////////////////////////////////////////////////////////////////// void _Cdecl PutPixel(int x,int y,int color) { long addr; int page; char far *videoptr = (char far *)0xa0000000L; if (x >= 0 && x < 800 && y >= 0 && y < 600) { addr = VARM_GRAPH_800(x,y); page = (int)(addr >> 16); set_vbe_page(page); *(videoptr+(unsigned int)(addr&0xffff))= color; } } ///////////////////////////////////////////////////////////////////////////////////////////////// //在24位图像中,没有“DAC色表”,也没有“图像数据区”。唯一留给我们的只有图像上所有点的颜色值。 //因为每个颜色都用BGR三种颜色来表示,而每个颜色占用1个字节,所以在24位图像中,每1个点就占用了 //3个字节。 //那没有“DAC”色表,也没有‘数据图像区’我们怎么来显示图象呢?很简单, 24位图给我们提供了个更 //加简单的方法:“所有点的颜色值”。既然是所有点,那么只要把这些点按照他们的颜色重新画出来就是 //该图像完整的信息了。 ///////////////////////////////////////////////////////////////////////////////////////////////// void Show_BMP(char *File_Name, int x, int y) { int i, j, width, color; FILE *fp; unsigned char *buffer; RGBQUAD *RGB; BITMAPFILEHEADER *FileHead; BITMAPINFOHEADER *InfoHead; RGB = (RGBQUAD *)malloc(sizeof(RGBQUAD)); FileHead = (BITMAPFILEHEADER *)malloc(sizeof(BITMAPFILEHEADER)); InfoHead = (BITMAPINFOHEADER*)malloc(sizeof(BITMAPINFOHEADER)); if (RGB == NULL || FileHead == NULL || InfoHead == NULL) return; if ((fp=fopen(File_Name,"rb")) == NULL) { printf("BMP File not exist ..."); return; } fread(FileHead,sizeof(BITMAPFILEHEADER),1,fp); if (FileHead->bfType!='BM') { printf("BMP File type Error ..."); fclose(fp); return; } fread(InfoHead,sizeof(BITMAPINFOHEADER),1,fp); if (InfoHead->biCompression !=0 || (InfoHead->biBitCount!=8 && InfoHead->biBitCount!=24)) { printf("BMP File not Support Compression type ..."); fclose(fp); return; } if ((int)InfoHead->biBitCount == 8) // 色深=8(256色图片) { width =((int)InfoHead->biWidth+3)/4*4; // 每行字节数--4的整数倍 if ((buffer = (unsigned char *)malloc(width)) == NULL) // 申请缓冲区 { fclose(fp); return; } for (i = 0 ; i < 256 ; i++) { fread(RGB,sizeof(RGBQUAD),1,fp); setpal(i,RGB->Red>>2,RGB->Green>>2,RGB->Blue>>2); } for (j = (int)InfoHead->biHeight-1 ; j >= 0 ; j--) { fread(buffer,width,sizeof(unsigned char),fp); for (i = 0; i < width; i++) PutPixel(i+x,j+y,buffer[i]); } free(buffer); } else if ((int)InfoHead->biBitCount == 24) // 色深=24(真彩色图片) { register RGB16M *buffer; if ((buffer = malloc(width*sizeof(RGB16M))) == NULL) { fclose(fp); return; } for (j = (int)InfoHead->biHeight-1 ; j >= 0 ; j--) { fread(buffer,width,sizeof(RGB16M),fp); for (i = 0 ; i < width ; i++) { color = makecol16(buffer[i].Red,buffer[i].Green,buffer[i].Blue); PutPixel(i,j,color); } } } free(FileHead); free(InfoHead); free(RGB); } void main(void) { InitGraph(); Show_BMP("logo.BMP",0,0); getch(); CloseGraph(); } |
![]() |
#6
ba_wang_mao2010-04-08 09:29
//原创:在800*600*64K真彩色模式下显示BMP图片和画点
//作者:成都理工学院 #include <dos.h> #include <stdio.h> #include <mem.h> #include <alloc.h> #include <stdlib.h> #include <conio.h> #define VBE800X600X64K 0X114 #define RGB(r,g,b) ((((unsigned int)(r)>>3)<<11) + (((unsigned int)(g)>>2)<<5) + ((b)>>3)) #define SCREEN_WIDTH 800L #define SCREEN_HIGH 600L #define VARM_GRAPH_800_600_256(x,y) (((unsigned long)y<<9L)+((unsigned long)y<<8L)+((unsigned long)y<<5L)+((unsigned long)(x))) #define VARM_GRAPH_800_600_16M(x,y) (((((unsigned long)y<<9L)+((unsigned long)y<<8L)+((unsigned long)y<<5L))<<1L) + (((unsigned long)x)<<1L)) #define PALETTE_READ 0x3C7 /*VGA系统调色板读端口*/ #define PALETTE_WRITE 0x3C8 /*VGA系统调色板写端口*/ #define PALETTE_DATA 0x3C9 /*VGA系统调色板数据端口*/ /*第一部分为位图文件头BITMAPFILEHEADER,其定义如下:*/ typedef struct tagBITMAPFILEHEADER { unsigned int bfType; /*指定文件类型,*.bmp文件的头两个字节都是"BM"*/ unsigned long bfSize; /*指定文件大小,包括这14个字节*/ unsigned int Reserved1; /*为保留字,不用考虑*/ unsigned int reserved2; /*为保留字,不用考虑*/ unsigned long bfOffset; /*为从文件头到实际的位图数据的偏移字节数,前三个部分的长度之和。*/ }BITMAPFILEHEADER; /*第二部分为位图信息头BITMAPINFOHEADER,这个结构的长度是固定的,为40个字节其定义如下:*/ typedef struct tagBITMAPINFOHEADER { unsigned long biSize; /*指定这个结构的长度,为40*/ unsigned long biWidth; /*指定图象的宽度,单位是象素*/ unsigned long biHeight; /*指定图象的高度,单位是象素*/ unsigned int biPlanes; /*必须是1,不用考虑*/ unsigned int biBitCount; /*指定表示颜色时要用到的位数,常用的值为1(黑白二色图),4(16色图),8(256色),24(真彩色图)*/ unsigned long biCompression; /*指定位图是否压缩,有效的值为BI_RGB,BI_RLE8,BI_RLE4,BI_BITFIELDS*/ unsigned long biSizeImage; /*指定实际的位图数据占用的字节数*/ unsigned long biXpolsPerMeter; /*指定目标设备的水平分辨率,单位是每米的象素个数。*/ unsigned long biYpelsPerMeter; /*指定目标设备的垂直分辨率,单位同上。*/ unsigned long biClrUsed; /*指定本图象实际用到的颜色数,如果该值为零,则用到的颜色数为2的biBitCount次方。*/ unsigned long biClrImportant; /*指定本图象中重要的颜色数,如果该值为零,则认为所有的颜色都是重要的。*/ }BITMAPINFOHEADER; typedef struct tagRGBQUAD /* 256 RGB像素类型 */ { unsigned char Blue; unsigned char Green; unsigned char Red; unsigned char Reserved; }RGBQUAD; typedef struct tagRGB16M /* 16M RGB像素类型 */ { unsigned char Blue; unsigned char Green; unsigned char Red; }RGB16M; int g_cur_vbe_page = 0; ///////////////////////////////////////////////////////////////////////////////////////////////// //图形模式初始化子程序 ///////////////////////////////////////////////////////////////////////////////////////////////// void _Cdecl InitGraph(unsigned int mode) { _AX = 0x4f02; _BX = mode; __int__(0x10); if(_AH != 0) { puts("Can't Initialize the graphics mode!"); exit(1); } } ///////////////////////////////////////////////////////////////////////////////////////////////// //关闭图形模式,回到文本模式子程序 ///////////////////////////////////////////////////////////////////////////////////////////////// void _Cdecl CloseGraph(void) { _AX = 0x4f02; _BX = 0x03; __int__(0x10); } ///////////////////////////////////////////////////////////////////////////////////////////////// //显存换页函数 ///////////////////////////////////////////////////////////////////////////////////////////////// void _Cdecl set_vbe_page(int page) { if (g_cur_vbe_page != page) { _BX = 0; _DX = g_cur_vbe_page = page; _AX = 0x4F05; __int__(0x10); } } ///////////////////////////////////////////////////////////////////////////////////////////////// //16M真彩色800*600写点 ///////////////////////////////////////////////////////////////////////////////////////////////// void PutPixel16M(int x,int y,int Color) { /* int page; char far *videoptr = (char far *)0xa0000000L; long addr = VARM_GRAPH_800_600_16M(x,y); if (x >= 0 && x < SCREEN_WIDTH && y >= 0 && y < SCREEN_HIGH) { page = (int)(addr >> 16); set_vbe_page(page); *(videoptr + (unsigned int)(addr & 0xFFFF))= Color & 0xFF; *(videoptr + (unsigned int)(addr & 0xFFFF)+1)= Color>>0x08; } */ long addr = VARM_GRAPH_800_600_256(x,y); int far *videoptr16 = (int far *)MK_FP(0xa000, 0); int page; page = (int)(addr >> 15); set_vbe_page(page); *(videoptr16 + (unsigned int)(addr & 0xFFFF))= Color; } ///////////////////////////////////////////////////////////////////////////////////////////////// //在24位图像中,没有“DAC色表”,也没有“图像数据区”。唯一留给我们的只有图像上所有点的颜色值。 //因为每个颜色都用BGR三种颜色来表示,而每个颜色占用1个字节,所以在24位图像中,每1个点就占用了 //3个字节。那没有“DAC”色表,也没有‘数据图像区’我们怎么来显示图象呢?很简单, 24位图给我们提供了个更 //加简单的方法:“所有点的颜色值”。既然是所有点,那么只要把这些点按照他们的颜色重新画出来就是 //该图像完整的信息了。 ///////////////////////////////////////////////////////////////////////////////////////////////// void Show_BMP(char *File_Name) { int i, j, width ; register BITMAPFILEHEADER *FileHead; register BITMAPINFOHEADER *InfoHead; FILE *fp; if ((FileHead = (BITMAPFILEHEADER *)malloc(sizeof(BITMAPFILEHEADER))) == NULL) return; if ((InfoHead = (BITMAPINFOHEADER*)malloc(sizeof(BITMAPINFOHEADER))) == NULL) return; if ((fp = fopen(File_Name,"rb")) == NULL) { printf("BMP File not exist ..."); return; } fread(FileHead,sizeof(BITMAPFILEHEADER),1,fp); if (FileHead->bfType!='BM') { printf("BMP File type Error ..."); fclose(fp); return; } fread(InfoHead,sizeof(BITMAPINFOHEADER),1,fp); if (InfoHead->biCompression !=0 || (InfoHead->biBitCount!=8 && InfoHead->biBitCount!=24)) { printf("BMP File not Support Compression type ..."); fclose(fp); return; } width =((int)InfoHead->biWidth+3)/4*4; // 每行字节数--4的整数倍 if ((int)InfoHead->biBitCount == 24) { register RGB16M *buffer; if ((buffer = malloc(width*sizeof(RGB16M))) == NULL) { fclose(fp); return; } for (j = (int)InfoHead->biHeight-1 ; j >= 0 ; j--) { fread(buffer,width,sizeof(RGB16M),fp); for (i = 0 ; i < width ; i++) PutPixel16M(i,j,RGB(buffer[i].Red,buffer[i].Green,buffer[i].Blue)); } } free(FileHead); free(InfoHead); fclose(fp); } void main(void) { InitGraph(VBE800X600X64K); Show_BMP("d:\\logo.BMP");//显示一幅16M真彩色BMP图片 getch(); CloseGraph(); } /* //满屏显示RGB(71,201,61)=绿色,你可以用WINDOWS中的RGB其它颜色试试 void main(void) { int x,y; int Color = RGB(71,201,61); InitGraph(VBE800X600X64K); for (y=0;y<600;y++) for (x=0;x<800;x++) PutPixel16M(x,y,Color); getch(); CloseGraph(); } */ |
![]() |
#7
纯洁2010-07-21 01:28
![]() ![]() |