为了正常的体验网站,请在浏览器设置里面开启Javascript功能!

【精品】如何在WIN-TC中或TC++30中把一张BMP格式的图片显示出来

2017-09-16 50页 doc 112KB 26阅读

用户头像

is_260251

暂无简介

举报
【精品】如何在WIN-TC中或TC++30中把一张BMP格式的图片显示出来【精品】如何在WIN-TC中或TC++30中把一张BMP格式的图片显示出来 如何在WIN-TC中或TC++3.0中把一张BMP格式的图片显 示出来? 下面的是>随书光盘上的代码,我在TC2.0下编译通过. 它是利用了抖动技术显示了8bit和24bit的位图(也就是256色和16M色位图),应该能满足你的需要. 不过,我想问下,你老师教过抖动显示吗? #include #include #include #include #define NoError 0 #define ErrorFileOpen 1...
【精品】如何在WIN-TC中或TC++30中把一张BMP格式的图片显示出来
【精品】如何在WIN-TC中或TC++30中把一张BMP格式的图片显示出来 如何在WIN-TC中或TC++3.0中把一张BMP格式的图片显 示出来? 下面的是<>随书光盘上的代码,我在TC2.0下编译通过. 它是利用了抖动技术显示了8bit和24bit的位图(也就是256色和16M色位图),应该能满足你的需要. 不过,我想问下,你老师教过抖动显示吗? #include #include #include #include #define NoError 0 #define ErrorFileOpen 1 #define ErrorFileType 2 #define ErrorImageColor 3 typedef struct tagBITMAPFILEHEADER { unsigned int bfType; unsigned long bfSize; unsigned int bfReserved1; unsigned int bfReserved2; unsigned long bfoffBits; }BITMAPFILEHEADER; typedef struct tagBITMAPINFOHEADER { unsigned long biSize; unsigned long biWidth; unsigned long biHeight; unsigned int biPlanes; unsigned int biBitCount; unsigned long biCompression; unsigned long biSizeImage; unsigned long biXPelsPerMeter; unsigned long biYPelsPerMeter; unsigned long biClrUsed; unsigned long biClrImportant; } BITMAPINFOHEADER; typedef struct tagRGBQUAD { unsigned char rgbBlue; unsigned char rgbGreen; unsigned char rgbRed; unsigned char rgbReserved; } RGBQUAD; unsigned char PalReg[17]= { 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,0}; unsigned char StandardPal[48]= { 0, 0, 0, 32, 0, 0, 0,32, 0, 32,32, 0, 0, 0,32, 32, 0,32, 0,32,32, 32,32, 32, 48, 48,48, 63, 0, 0, 0,63, 0, 63,63, 0, 0, 0,63, 63, 0,63, 0,63,63, 63,63,63, }; unsigned char LightnessMatrix [16][16]= { { 0,235,59,219,15,231,55,215,2,232,56,217,12,229,52,213}, {128,64,187,123,143,79,183,119,130,66,184,120,140,76,180,116}, {33,192,16,251,47,207,31,247,34,194,18,248,44,204,28,244}, {161,97,144,80,175,111,159,95,162,98,146,82,172,108,156,92}, {8,225,48,208,5,239,63,223,10,226,50,210,6,236,60,220}, {136,72,176,112,133,69,191,127,138,74,178,114,134,70,188,124}, {41,200,24,240,36,197,20,255,42,202,26,242,38,198,22,252}, {169,105,152,88,164,100,148,84,170,106,154,90,166,102,150,86}, {3,233,57,216,13,228,53,212,1,234,58,218,14,230,54,214}, {131,67,185,121,141,77,181,117,129,65,186,122,142,78,182,118}, {35,195,19,249,45,205,29,245,32,193,17,250,46,206,30,246}, {163,99,147,83,173,109,157,93,160,96,145,81,174,110,158,94}, {11,227,51,211,7,237,61,221,9,224,49,209,4,238,62,222}, {139,75,179,115,135,71,189,125,137,73,177,113,132,68,190,126}, {43,203,27,243,39,199,23,253,40,201,25,241,37,196,21,254}, {171,107,155,91,167,103,151,87,168,104,153,89,165,101,149,85}, }; unsigned char ColorTable[2][2][2]= {{{0,12},{10,14}},{{9,13},{11,15}}}; unsigned char ColorMap[256][3]; int ShowBmp(char *FileName); int GetColor(unsigned char R,unsigned char G, unsigned char B,int X,int Y); void SetVideoMode(unsigned char Mode); void SetPalReg(unsigned char *palReg); void SetDacReg(unsigned char *DacReg, int Color, int Count); void PutPixel(int X, int Y, unsigned char Color); /* 主函数 */ void main (int argc, char *argv[]) { if(argc!=2) { printf("Usage:\tSHOW Filename.BMP\n"); exit(1); } ShowBmp(argv[1]); } /* 根据图像文件名,读取图像并利用抖动技术进行显示 */ int ShowBmp(char *FileName) { FILE *Fp; BITMAPFILEHEADER FileHead; BITMAPINFOHEADER InfoHead; RGBQUAD RGB; int N, W,Y,X,C,Color; unsigned char Buffer[4096]; Fp=fopen(FileName,"rb"); if (Fp==NULL) return(ErrorFileOpen); fread(&FileHead,sizeof(BITMAPFILEHEADER),1,Fp); if(FileHead.bfType!='BM') { fclose(Fp); return(ErrorFileType); } fread(&InfoHead,sizeof(BITMAPINFOHEADER),1,Fp); if(InfoHead.biBitCount!=8 && InfoHead.biBitCount!=24) { fclose(Fp); return(ErrorImageColor); } /* 设置显示模式和显示区域 */ SetVideoMode(0x12); SetPalReg(PalReg); SetDacReg(StandardPal,0,16); /* 对两种不同色彩数的图像分别进行处理 */ if(InfoHead.biBitCount==8) /* 256色 */ { for (N=0;N<256;N++) { fread(&RGB, sizeof(RGBQUAD),1,Fp); ColorMap[N][0]=RGB.rgbRed; ColorMap[N][1]=RGB.rgbGreen; ColorMap[N][2]=RGB.rgbBlue; } W=(InfoHead.biWidth+3)/4*4; for(Y=InfoHead.biHeight-1;Y>=480;Y--) fread(Buffer,sizeof(unsigned char),W,Fp); for(;Y>0;Y--) { fread(Buffer,sizeof(unsigned char),W,Fp); for (X=0;X639;Y--) fread(Buffer,sizeof(unsigned char),W,Fp); for(;Y>=0;Y--) { fread(Buffer,sizeof(unsigned char),W,Fp); for(X=0;XL][(unsigned int)G*256/255>L][(unsigned int)B*256/255>L]); } void SetVideoMode(unsigned char Mode) { _AH=0x00; _AL=Mode; geninterrupt(0x10); } void SetPalReg(unsigned char *PalReg) { _ES=FP_SEG((unsigned char far*)PalReg); _DX=FP_OFF((unsigned char far*)PalReg); _AX=0x1002; geninterrupt(0x10); } void SetDacReg(unsigned char *DacReg,int Color,int Count) { _ES=FP_SEG((unsigned char far*)DacReg); _DX=FP_OFF((unsigned char far*)DacReg); _AX=0x1012; _BX=Color; _CX=Count; geninterrupt(0x10); } /* 在对应位置显示像素色彩 */ void PutPixel(int X, int Y, unsigned char Color) { _AH=0x0C; _AL=Color; _CX=X; _DX=Y; geninterrupt(0x10); } 16色位图的显示 文:吴进/Luckylai 对于象大家常用TC的16色图形模式编程的初学者,如果能在程序里使用图片那就会方便很多了,以前在TC256上看见吴进写的《TC的16色BMP闪电显示(66k) 》的代码,发现写的的确不错,而且绝对能在TC的initgraph()初始化的BGI模式下使用。美中不足是会产生中间文件。后来想了一下,干脆就使用那个中间文件,用程序把BMP转换成中间文件,直接用putimage输出不就好了。说到这里,可能大家还不能明白,不要紧下面我慢慢说起。 (一)吴进的《TC的16色BMP闪电显示 》 Turbo C2.0图形模式下显示BMP位图的高速方法,不同于一般的putpixel和line绘制的方法,速度之快令你感觉不到显示的过程,而且绝对能在TC的initgraph()初始化的BGI模式下使用。 /*程序:吴进*/ /*注意:编译程序时内存模式必需为 Large 以上模式*/ #include "stdio.h" #include "dir.h" #include "dos.h" #include "graphics.h" char *malloc();/*malloc转换*/ char bmp_to_dat(char *bmp,char *dat) /*将16色BMP文件转换为可以用putimage输出的格式,bmp为原BMP文件,dat为转化文件*/ {unsigned char c[8],scan_times,scan_pixs; unsigned char workpos;int i,j,k,n,nowpos,iw,ih; static int color[16]={0,4,2,6,1,5,3,7,8,12,10,14,9,13,11,15}; unsigned char workline[640],scanline[640]; FILE *fp,*targetfp; union {unsigned char value; struct {unsigned cl:4; unsigned ch:4; }color; }mycolor; if((fp=fopen(bmp,"rb"))==NULL)return(0); targetfp=fopen(dat,"wb"); fseek(fp,18,SEEK_SET); iw=0;ih=0; fread(&iw,4,1,fp); /*读图像宽度*/ fread(&ih,4,1,fp); /*读图像高度*/ if(iw==0&&ih==0&&iw>640&&ih>480) {fclose(fp);fclose(targetfp);return(0);} iw--;ih--; /*?putimage中的长宽比实际数值少1*/ scan_times=iw/8+1; /*行处理单位数*/ scan_pixs=scan_times*4; /*行像素字节数?1单位=4字节*/ fputc(iw%256,targetfp); /*填充信息头:长、宽部分*/ fputc(iw/256,targetfp); fputc(ih%256,targetfp); fputc(ih/256,targetfp); fseek(fp,-scan_pixs,SEEK_END); for(j=0;j<=ih;j++) {nowpos=0; fread(scanline,scan_pixs,1,fp); fseek(fp,-scan_pixs*2,SEEK_CUR); for(n=3;n>=0;n--) /*解码4个位面*/ {for(i=0;i>n&1)<<(7-k); workline[nowpos]=workpos;nowpos++; }} fwrite(workline,scan_pixs,1,targetfp); } fclose(fp);fclose(targetfp); return(1); } main() {int gd=VGA,gm=VGAHI,n; char *buffer,bmpfile[13],_16file[13]={0}; FILE *fp; struct ffblk *ff; initgraph(&gd,&gm,""); puts("(c)2001 BY Wu Jin"); printf("Now begin showing 16 colors BMP...\n\n"); puts("Select 16 color BMP file to put:"); printf("0. Exit\n1. zx.bmp\n2. mm.bmp\n3.Other bmp file(*.bmp In this directory)\n"); while(1) {n=getch(); switch(n) {case 0 :continue; case '0':exit(0); case '1':strcpy(bmpfile,"zx.bmp");goto OUT; case '2':strcpy(bmpfile,"mm.bmp");goto OUT; case '3':{printf("Input filename(*.bmp):"); gets(bmpfile);goto OUT; } } } OUT: strncpy(_16file,bmpfile,strlen(bmpfile)-3); strcat(_16file,"dat"); if(!bmp_to_dat(bmpfile,_16file)) {puts("File Error!");closegraph();exit(0);} fp=fopen(_16file,"rb"); findfirst(_16file,ff,FA_ARCH); if((buffer=malloc(ff->ff_fsize))==NULL)exit(0); n=0; while(!feof(fp)) {buffer[n]=fgetc(fp); n++; } for(n=0;n<100;n++) {putimage(350-n,n/2,buffer,COPY_PUT); } getch(); closegraph(); free(buffer); fclose(fp); } 上面的程序没有点基本工也看不懂。我来解释一下。先调用bmp_to_dat()把BMP转换成TC可以直接putimage输出的格式的文件,宽展名DAT。至于MAIN函数不用管太多,有价值的就一句putimage(350-n,n/2,buffer,COPY_PUT);输出而已。 (二)改进 由于吴进的程序是在输出图片前进行格式转换,因此时间都耗在转换中了。而我使用转换程序把BMP先转换完毕。而随程序发布的就只有中间文件了(暂时命为PIC文件)。 下面是转换程序。(其实就是照搬吴进的程序,捎做改进) /*程序设计:luckylai*/ /*文件名:bmp2pic.c */ #include "stdio.h" #include "dir.h" #include "dos.h" char bmp_to_dat(char *bmp,char *dat) /*将16色BMP文件转换为可以用putimage输出的格式,bmp为原BMP文件,dat为转化文件*/ {unsigned char c[8],scan_times,scan_pixs; unsigned char workpos;int i,j,k,n,nowpos,iw,ih; static int color[16]={0,4,2,6,1,5,3,7,8,12,10,14,9,13,11,15}; unsigned char workline[640],scanline[640]; FILE *fp,*targetfp; union {unsigned char value; struct {unsigned cl:4; unsigned ch:4; }color; }mycolor; if((fp=fopen(bmp,"rb"))==NULL)return(0); targetfp=fopen(dat,"wb"); fseek(fp,18,SEEK_SET); iw=0;ih=0; fread(&iw,4,1,fp); /*读图像宽度*/ fread(&ih,4,1,fp); /*读图像高度*/ if(iw==0&&ih==0&&iw>640&&ih>480) {fclose(fp);fclose(targetfp);return(0);} iw--;ih--; /*?putimage中的长宽比实际数值少1*/ scan_times=iw/8+1; /*行处理单位数*/ scan_pixs=scan_times*4; /*行像素字节数?1单位=4字节*/ fputc(iw%256,targetfp); /*填充信息头:长、宽部分*/ fputc(iw/256,targetfp); fputc(ih%256,targetfp); fputc(ih/256,targetfp); fseek(fp,-scan_pixs,SEEK_END); for(j=0;j<=ih;j++) {nowpos=0; fread(scanline,scan_pixs,1,fp); fseek(fp,-scan_pixs*2,SEEK_CUR); for(n=3;n>=0;n--) /*解码4个位面*/ {for(i=0;i>n&1)<<(7-k); workline[nowpos]=workpos;nowpos++; }} fwrite(workline,scan_pixs,1,targetfp); } fclose(fp);fclose(targetfp); return(1); } void main(int argc,char *aaaa[]) { int i;char a1[30],a2[30]; printf("\n\nUsage: Bmp2pic -inputfile [*.bmp] -outputfile[*.pic]\ncopy right (C) 1989-2002 CEN TER COMPUTER CO, LTD.\n"); if(aaaa[1]==NULL) { printf("\nInput Filename:"); gets(a1); aaaa[1]=a1; // if(aaaa[2]==NULL) printf("\nOutput Filename:"); gets(a2); aaaa[2]=a2; } i=bmp_to_dat(aaaa[1],aaaa[2]); if(i==0) printf("Fail"); } 之后的事情就很简单了。 输出函数 #include "stdio.h" #include "dir.h" #include "dos.h" int Pic_Putout(int x,int y,char *filenames) {int n; char *buffer; FILE *fp; struct ffblk *ff; fp=fopen(filenames,"rb"); //打开PIC文件 findfirst(filenames,ff,FA_ARCH);//获得文件信息,主要是大小 if((buffer=malloc(ff->ff_fsize))==NULL)exit(0); putimage(x,y,buffer,COPY_PUT); //输出 free(buffer); fclose(fp); } 如果你要频繁使用这张图片,那么就只在初始化时打开一次文件,内存不要释放,请读者自己写好了。 (四)图片处理的问题 16色图片由于颜色信息少,因此处理上就得很讲究了。使用xnview114gb.exe这个免费软件吧(本站可以下载),功能强大。另外的他的抖动处理,可以使16色图片显示更多信息。 另外一个要点就是调色板的问题。使用ACDSEE等软件转换出来的16色,并不是的16色。他们使用了调色板。为了正确显示,建议使用WINDOWS自带的“画图”软件,进行处理。 /*********************************************** *******在DOS下显示16位色位图源程序************** ***********************************************/ #include #include #include #include #include #include #include #include #include #include #define closegr closegraph /*********************************************** *************位图文件头结构********************* ***********************************************/ typedef struct { int id; /*两字节的内容用来识别位图的类型: 'BM' : Windows 3.1x, 95, NT, „ 'BA' :OS/2 Bitmap Array 'CI' :OS/2 Color Icon 'CP' :OS/2 Color Pointer 'IC' : OS/2 Icon 'PT' :OS/2 Pointer 注:因为OS/2系统并没有被普及开,所以在编程时,你只需判断第一个标识"BM"就行 */ long filesize; /*用字节示的整个文件的大小*/ long reserved; /*保留,必须设置为0*/ long dataoffset; /*从文件开始到位图数据开始之间的数据(bitmap data)之间的偏移量*/ long headersize; /*位图信息头(Bitmap Info Header)的长度,用来描述位图的颜色、压缩方法等。下面的长度表示: 28h - Windows 3.1x, 95, NT, „ 0Ch - OS/2 1.x F0h - OS/2 2.x 注:在Windows95、98、2000等操作系统中,位图信息头的长度并不一定是28h,因为微软已经制定出了新的BMP文件格式,其中的信息头结构变化比较大,长度加长。所以最好不要直接使用常数28h,而是应该从具体的文件中读取这个值。这样才能确保程序的兼容性。 */ long width; /*位图的宽度,以象素为单位*/ long height;/*位图的高度,以象素为单位*/ int Planes; /*位图的位面数(注:该值将总是1)*/ int Pixe; /*每个象素的位数 1 - 单色位图(实际上可有两种颜色,缺省情况下是黑色和白色。你可以自己定义这两种颜色) 4 - 16 色位图 8 - 256 色位图 16 - 16bit 高彩色位图 24 - 24bit 真彩色位图 32 - 32bit 增强型真彩色位图 */ long Compression; /*压缩说明: 0 - 不压缩 (使用BI_RGB表示) 1 - RLE 8-使用8位RLE压缩方式(用BI_RLE8表示) 2 - RLE 4-使用4位RLE压缩方式(用BI_RLE4表示) 3 - Bitfields-位域存放方式(用BI_BITFIELDS表示) */ long bmpDataSize; /*用字节数表示的位图数据的大小。该数必须是4的倍数*/ long XPelsPerMeter;/*用象素/米表示的水平分辨率*/ long YPelsPerMeter;/*用象素/米表示的垂直分辨率*/ long ClrUsed; /*位图使用的颜色数。如8-比特/象素表示为100h或者 256*/ long ClrImportant; /*指定重要的颜色数。当该域的值等于颜色数时(或者等于0时),表示所有颜色都一样重要*/ }BMPHEAD; BMPHEAD BmpHead; char convert[16] = {0x0,0x4,0x2,0x6,0x1,0x5,0x3,0x7,0x8,0xc,0xa,0xe,0x9,0xd,0x3,0xf};/*BM P色彩与VGA色对照表*/ unsigned char * bmp_data; int fp; /********************************************** ************ BGI初始化函数********************* **********************************************/ void initgr(void) { int gd = DETECT, gm = 0; /* 和gd = VGA,gm = VGAHI是同样效果 */ registerbgidriver(EGAVGA_driver);/* 注册BGI驱动后可以不需要.BGI文件的支持运行 */ initgraph(&gd, &gm, ""); } /*********************************************** *************位图文件头读取函数***************** ***********************************************/ int read_bmp_head(char *bmp_filename) { if((fp=open(bmp_filename,O_RDONLY))==-1)/*打开位图文件*/ { printf("%s%s",bmp_filename," is not found."); return 1; } read(fp,&BmpHead,sizeof(BMPHEAD));/*读取BMP文件的信息头*/ if(BmpHead.id!=0x4d42) /*判断是否是BMP文件*/ { printf("%s%s","'",bmp_filename,"' is not BMPfile"); return 1; } return 0; } /*********************************************** **************纠正宽度函数********************** ***********************************************/ int correct_width(int width) { int factual_width; if(width%4==0&&(width/4)%2==0); else while(width%4!=0||(width/4)%2!=0)width++; factual_width=width; return factual_width; } /*********************************************** *************读位图文件并显示函数*************** ***********************************************/ void put_bmp(char * bmpfile,int x,int y) { int read_bmp_head_return,i,j,d=0,cn; bmp_data=(unsigned char *)malloc(BmpHead.bmpDataSize*sizeof(unsigned char)); if((read_bmp_head_return=read_bmp_head(bmpfile))==1) { getch(); exit(1); } lseek(fp,BmpHead.dataoffset,SEEK_SET); read(fp,bmp_data,BmpHead.bmpDataSize);/*读取颜色数据到缓冲区内*/ cn=correct_width(BmpHead.width); for(i=BmpHead.height;i>0;i--) for(j=0;j>4]);/*用高4位画1个点*/ putpixel(x+j++,y+i,convert[bmp_data[d]&0xf]); /*用低4位画1个点*/ d++; } free(bmp_data); close(fp); } /*********************************************** *************主函数***************************** ***********************************************/ int main(void) { initgr(); put_bmp("pix.bmp",320,240); getch(); closegr(); return 0; } /* 这是上面程序的一个应用 XP WIN2000 可以不用再驱动鼠标了 */ #include "Conio.h" #include #include #include "graphics.h" #define closegr closegraph union REGS regs; void initgr(void) /* BGI初始化 */ { int gd = DETECT, gm = 0; /* 和gd = VGA,gm = VGAHI是同样效果 */ registerbgidriver(EGAVGA_driver);/* 注册BGI驱动后可以不需要.BGI文件的支持运行 */ initgraph(&gd, &gm, ""); } int initmouse(int xmin,int xmax,int ymin,int ymax) { int retcode; regs.x.ax=0; int86(0x33,?s,?s); retcode=regs.x.ax; if(retcode==0)/*ax=0 安装失败*/ return 0; regs.x.ax=7; regs.x.cx=xmin; regs.x.dx=xmax; int86(0x33,?s,?s); /* 设置水平位置最大最小值*/ regs.x.ax=8; regs.x.cx=ymin; regs.x.dx=ymax; int86(0x33,?s,?s); /* 设置垂直位置最大最小值*/ return retcode; } int read(int *mx,int *my,int *mbutt) /*对鼠标的位置和按键状态函数*/ { int x0=*mx,y0=*my,buto=0; int xnew,ynew; do { regs.x.ax=3; int86(0x33,?s,?s);/* 取按键状态及鼠标位置 */ xnew=regs.x.cx; ynew=regs.x.dx; *mbutt=regs.x.bx; }while(xnew==x0&&ynew==y0&&*mbutt==buto);/*等到状态改变*/ if(*mbutt>>2<<7) { *mx=xnew; *my=ynew; return 2; /*中键按下*/ } else if(*mbutt>>1<<7) { *mx=xnew; *my=ynew; return 1; /*右键按下*/ } else if(*mbutt<<7) { *mx=xnew; *my=ynew; return -1; /*左键按下*/ } else { *mx=xnew; *my=ynew; return 0; /*无键按下*/ } } void cursor(int x,int y,char *pic) /*画鼠标*/ { put_bmp(pic,x,y); } int mouse_move(int *x,int *y,int *button) { int x0=*x,y0=*y,mouse_button; mouse_button=read(x,y,button); cursor(x0,y0,"pix.bmp"); cursor(*x,*y,"pix.bmp"); return mouse_button; } int mouse_bound(int *x,int *y,int m1,int n1,int m2) { if(m1<*x&&*x # include # include # include unsigned char convert (); main() { int 1, i, j, k, q, h; int driver=VGA, mode=VGAHI; int lenth, high, number, p, m; unsigned size; unsigned char ch, a[8], b[4], e[4][8]; FILE *fp; char *s; fp=fopen (“party. bmp” , “rb”); fseek (fp, 18, 0); lenth=getw (fp); /* graphics width */ fseek (fp, 22, 0); high=getw (fp); #/* graphics high */ #if ((lenth%8)==0) number= (lenth+8)/8*4 #/* bytes of each line */ # else number=4*(ceil ((double)1enth/8)); up=number/4; mif ((lenth%8)!=0) m=p; {/* bytes of each line/4 */ else m=p-1; size=6+number*(high+1) /* need memory bytes of graphics */ if ((s=char *) malloc (size))==NULL) { printf (“malloc error !,n”); exit (0);} s[0]=lenth & 0x00ff; s[1]=(lenth& 0xff00)>>8; s[2]=high & 0x00ff; s[3]=(high & 0xff00)>>8; for (i=4; i=0; 1--) #for (q=0; q>1; {a[2]=(ch&0x4)>>2;a[3]=(ch&0x8)>>3; a[4]=(ch&0x10)>>4;a[5]=(ch&x20)>>5; a[6]=(ch&0x40)>>6;a[7]=(ch&0x80)>>7; h=7; for (j=0; j<2; i++) for (j=0; j<4; i++) { e[j][i+2*k]=a[h]; h--; } } #for (i=0; i<4; i++) { # b[i]=(e[i][,]<<7)+(e[i][1]<<6)+(e[i][2]<<5)+ #(e[i][3]<<4)+(e[i][4]<<3)+(e[i][5]<<2)+ #(e[i][6]<<1)+(e[i][7]); u s[4+number *1+q]=b[0]; s[4+number *1+q+p]=b[1]; m s[4+number *1+q+2*p]=b[2]; s[4+number *1+q+3*p]=b[3]; { } fclose (fp); initgraph (&driver, &mode, “d:,,tc”); putimage (0, 0, s, 0); getch(); free(s): closegraph(); } unsigned char convert (unsigned char ch) /* bmp color convert vga color */ { unsigned char c[2]; int i; #c[0]=(ch&0xf0)>>4; #c[1]=ch&0x0f; #for (i=0; i<2; i++) { #if (c[i]==0x01) {c[i]=0x04; continue;} uif (c[i]==0x03) {c[i]=0x6; continue;} mif (c[i]==0x04) {c[i]=0x01; continue;} {if (c[i]==0x06) {c[i]=0x03; continue;} if (c[i]==0x07) {c[i]=0x8; continue;} if (c[i]==0x08) {c[i]=0x07; continue;} if (c[i]==0x09) {c[i]=0xc; continue;} if (c[i]==0x0b) {c[i]=0xe; continue;} if (c[i]==0x0c) {c[i]=0x9; continue;} if (c[i]==0x0e) c[i]=0x0b; } ch=(c[0]<<4)+c[1]; return ch; #} # /* 函数功能:显示JPG和GIF图片 参数说明 pDC:设备环境对象 strPath:要显示的图片路径 x:要显示的X位置 y:要显示的Y位置 */ BOOL CShowJpegView::ShowJpgGif(CDC* pDC,CString strPath, int x, int y) { IStream *pStm; CFileStatus fstatus; CFile file; LONG cb; //打开文件并检测文件的有效性 if (file.Open(strPath,CFile::modeRead)&& file.GetStatus(strPath,fstatus)&& ((cb = fstatus.m_size) != -1)) { HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE, cb); LPVOID pvData = NULL; 下面的程序是在tc下读BMP文件 注意: 1。tc支持16色,所以所读的图片要是16色图片 2。图片的的存放是从最后一行开始的,倒过来存放的 3。每行的字节数是4的倍数 #include "stdio.h" #include "graphics.h" #include "alloc.h" #include "stdlib.h" #include "math.h" typedef struct tagBITMAPFILEHEADER { unsigned int bfType; unsigned long bfSize; unsigned int bfReserved1; unsigned int bfReserved2; unsigned long bfOffBits; }BITMAPFILEHEADER; typedef struct tagBITMAPINFOHEADER { unsigned long biSize; long biWidth; long biHeight; unsigned int biPanes; unsigned int biBitCount; unsigned long biCompression; unsigned long biSizeImage; long biXPelsPerMeter; long biYPelsPerMeter; unsigned long biClrUsed; unsigned long biClrImportant; }BITMAPINFOHEADER; typedef struct tagRGBQUAD { unsigned char rgbBlue; unsigned char rgbGreen; unsigned char rgbRed; unsigned char rgbReserved; }RGBQUAD; typedef struct tagBITMAPINFO { BITMAPINFOHEADER bmiHeader; RGBQUAD bmiColors[]; }BITMAPINFO; int xmax; int ymax; void InitGraph() { int mod=EGA; int dr=EGAHI; initgraph(&mod,&dr,""); xmax=getmaxx(); ymax=getmaxy(); } void CloseGraph() { closegraph(); } void Exit(char *ErrorCode) { printf("%s",ErrorCode); getch(); exit(0); } long WidthBytes(long Width,int BitCount) { long WBytes; WBytes=(Width*BitCount+31)/8; WBytes=WBytes/4*4; return WBytes; } unsigned char SetPalette(int Colors,unsigned char data) { switch(Colors) { case 16: switch(data) { case 1: return 4; case 4: return 1; case 3: return 6; case 6: return 3; case 9: return 12; case 12: return 9; case 11: return 14; case 14: return 11; default: return data; } case 2: if(data==1) return 15; else return 0; } } void main() { long i,j; long WBytes; int Colors; long Height,Width; FILE *fp; void *Temp=NULL; BITMAPFILEHEADER bfh; BITMAPINFOHEADER bih; unsigned char SrcData,data; InitGraph(); if((fp=fopen("pic1.bmp","rb"))==NULL) { Exit("Can Not Open The File.\n"); } fread(&bfh,sizeof(BITMAPFILEHEADER),1,fp); if(bfh.bfType!='M'*256+'B') { Exit("This Is Not A Bmp File.\n"); } fread(&bih,sizeof(BITMAPINFOHEADER),1,fp); Height=bih.biHeight; Width=bih.biWidth; WBytes=WidthBytes(Width,bih.biBitCount); Colors=1<=0;i--) { fseek(fp,54+Colors*sizeof(RGBQUAD)+i*WBytes,SEEK_SET); for(j=0;j>7)%2); putpixel(j,Height-1-i,data); } else { data=SetPalette(Colors,(SrcData>>(7-j%8))%2); putpixel(j,Height-1-i,data); } } } } getch(); CloseGraph(); } 在C语言中,我们也可以给软件加上一个好的封面,这会给你的程序添色不少。 学习目标 ?BMP文件的存储格式 ?DOS方式下调用BMP图像的手段 ?艺术再现BMP图像 BMP文件的存储格式 BMP文件是标准的Windows位图文件,有16色、256色、16位真彩色及24位真彩色等格式。客观存在按文件头、图像控制信息、彩色表和位图点阵数据的格式来存储。文件头是定义图像文件的类型、长度等的数据结构:图像控制信息是定义图像颜色格式、图像大小、颜色数等的数据结构:彩色表是定义图像颜色的调色板的数组位图点阵,是定义图像数据的数组。 未经压缩的BMP文件中,位图点阵信息是按扫描线从下至上(bottom to top)存储的,即图像的第一个像素值在位图阵列的左下角,最后一个像素值在位图阵列的右上角。对16色位图,每个像素占4位,每个字节存放相邻的两个像素值,高4位存放的第1个像素值在扫描线的前面,低4位存放的第2个像素值在扫描线后面。对256色位图,1个字节存放1个像素值。对24位位图,颜色表为空,位图数据的每3个字节对应1个像素值,其中每个字节分别对应该像素值的P、R、G值。 DOS方式下调用BMP图像的手段 再现一副非压缩静止位图,主要需下面三个步骤: ?设置显示模式; ?打开位图文件,读取图像控制信息,设置调色板; ?读取位图数据度进行显示。 若图像数据是以堵塞压缩的,那么先解压,然后再按上面的步骤进行。 设置显示模式 随着计算机硬件的不断发展,尤其是显示卡和显示椿性能的提高,显示效果越来越好。图像显示效果主要体现在图像分辨率和颜色两个方面,分辨率反映图像的清晰和谐,而颜色则反映了图像与物体本来颜色的逼真程度。虽然,对一个图形图像界面的评价涉及人的审美观,心理因素等主观原因,但也有客观的标准。高分辨率和真彩色是人分辨率追求的最高目标。现在,性能好的显示卡和显示器 :4(如SUPER VGA)能支持高达1024X768的分辨率,可以表示的颜色数目可达2种。对于DOS用户而言,常用的是640X480分辨率,16色、320X200分辨率,256色和640X480分辨率,256色等几种模式,它们分别是VGA,TVGA中的12h、13h和5dh模式。可通过直接调用DOS的10h中断来设置: 相应的函数定义如下: int Set640_480 (void) { asm mov ax,4fO2h asm mov bx,OlOlh asm int lob if((_AL==0x4f)&&(_AH==0)) { return(0); } return(1) } 调色板的设置 在DOS环境下显示Windows位图时,由于DOS调色板与Windows调色板不同,因此需自行设置Windows调色板,这样,图像才能不失真地显示所需的颜色并与原图像颜色相匹配。具体操作是从图像文件中读出彩色表数值,调用函数int86x写入Windows调色板控制区域。 相应的函数定义如下: void set_windows_palette16(unsigned char bmp_top[]) /*设置调色板*/ { int i; unsigned char chg[]={0,1,2,3,4,5,20,7,56,57,58,59,60,61,62,63}; int f[16]={0,4,2,6,1,5,3,8,7,12,10,14,9,13,11,15 }; for(i=O;i<-I 5;i++) (outportb(Ox3c8,chg[f]); outportb(Ox3c9,bmp top[54+i*4+2]/4); outportb(Ox3c9,bmp_top[5,~+i*4+ 1 ]/4); outportb(Ox3c9 ,bmp top [54+i* 4~-0]/4);} } int bmp_out(int x,int y,char *bmp_name) /*打开文件名为*bmp_name的文件,在(x,y)位置输出图像*/ { int i,j,k,l=0,c1,c2,x1,y1; unsigned char h,bmp_top[ 128],w,b=0x80,x0; char far *ptr=-(char far *)0xa0000000; char far *p; int fi16]={0,4,2,6,1,5,3,8,7,12,10,14,9,13,11,15 }; FILE *fp; if((fp=fopen(bmp name,"rb"))==NULL) return(1) fread(bmp_top,118,1,fp); set_windows_palette16(bmp_top); xl=bmp_top[18]+bmp_top[19]*256; y1=bmp_top[22]+bmp_top[23]*256; c1=(8-x1%8)/2; c2=x1%8; x0=b>>(x%8); ptr+=(rdS+80*(y+yl )); outportb(Ox3ce,5);outportb(Ox3cf, 2); for(i=O;i>=1; p=ptr-i*80+j; w=*p; *p=f[h>>4]; if(!b) {b=OxSO;j++; } if(x1%2&&l==x1-1) break; outportb(Ox3ce,8);outportb(Ox3cf,b);b>>= 1 p=ptr-i*80+j; w=*p; *p=f[h&OxOf]; if(!b) {b=Ox80;j++;} } if(c2) for(k--O;k>2; dacp.red=dacp.blue>>2; dacp.blue=pp; dacp.green=(dacp.green>>2); } asm push es _ES=FP_SEG(dacp); _DX=FP_OFF (dacp); asm mov bx,0 asm mov cx,colorcount asm mov ah,10h asm mov al,12h asm int 10h asm pop es fseek(bmpfp,bmpp.bfoff,SEEK_SET); buf=malloc(bmpp.biwidth); for(i=0;i #include #include long Addr[768]; int Mode; Set_Mode (int mode) { union REGS r; r.h.ah=0; r.h.al=mode; int86 (0x10,&r,&r); } Set_Graphics_Mode (unsigned x,unsigned y) { long i; if ((x<321)&&(y<201)) { Set_Mode (0x13); Mode=0x13; for (i=0;i<200;i++) Addr=320*i; } else if ((x<641)&&(y<401)) { Set_Mode (0x5c); Mode=0x5c; for (i=0;i<400;i++) Addr=640*i; } else if ((x<641)&&(y<481)) { Set_Mode (0x5d); Mode=0x5d; for (i=0;i<480;i++) Addr=640*i; } else if ((x<641)&&(y<481)) { Set_Mode (0x5d); Mode=0x5d; for (i=0;i<480;i++) Addr=640*i; } else if ((x<801)&&(y<601)) { Set_Mode (0x5e); Mode=0x5e; for (i=0;i<600;i++) Addr=800*i; } else if ((x<1025)&&(y<769)) { Set_Mode (0x62); Mode=0x62; for (i=0;i<768;i++) Addr=1024*i; } else { Set_Mode (3); printf ("Not support this mode .\n"); getch (); } } set_pattern () { int i; unsigned char pat[256][3]; struct SREGS inreg; union REGS reg; pat[0][0]=0;pat[0][1]=0;pat[0][2]=0; for (i=1;i<=255;i++) { pat[0]=(unsigned char)((float)(abs(i-127)*63)/127.0+0.5); pat[1]=(unsigned char)((float)(abs(i-127)*63)/127.0+0.5); pat[2]=63; } reg.x.ax=0x1012; reg.x.bx=0; reg.x.cx=256; reg.x.dx=FP_OFF(pat); inreg.es=FP_SEG(pat); int86x (0x10,?,?,&inreg); } plot (int x,int y,unsigned char color) { long offset; char Page; unsigned char far *address; switch (Mode) { case 0x13: offset=Addr[y]+x; address=(unsigned char far *)(0xa0000000L+offset); *address=color; break; case 0x5c: case 0x5d: case 0x5e: offset=Addr[y]+x; Page=(offset>>16); outportb (0x3c4,0xe); outportb (0x3c5,Page^0x02); offset=offset&65535; address=(unsigned char far *)(0xa0000000L+offset); *address=color; break; case 0x62: offset=Addr[y]+x; Page=y>>6; outportb (0x3c4,0xe); outportb (0x3c5,Page^0x02); offset=offset&65535; address=(unsigned char far *)(0xa0000000L+offset); *address=color; break; default: break; } } get_pixel (int x,int y) { long offset; char Page; unsigned char far *address; unsigned char color; switch (Mode) { case 0x13: offset=Addr[y]+x; address=(unsigned char far *)(0xa0000000+offset); color=*address; break; case 0x5c: case 0x5d: case 0x5e: offset=Addr[y]+x; Page=(offset>>16); outportb (0x3c4,0xe); outportb (0x3c5,Page^0x02); offset=offset&65535; address=(unsigned char far *)(0xa0000000L+offset); color=*address; break; case 0x62: offset=Addr[y]+x; Page=y>>6; outportb (0x3c4,0xe); outportb (0x3c5,Page^0x02); offset=offset&65535; address=(unsigned char far *)(0xa0000000L+offset); color=*address; break; default: break; } return (color); } randint (unsigned int range) { float sigma=423.1966; static double OldRand=0.4231967; double temp; temp=sigma*OldRand; OldRand=temp-(int)temp; return (int)(OldRand*(float)range); } void New_Col (int xa,int ya,int x,int y,int xb,int yb) { unsigned int color; color=abs(xa-xb)+abs(ya-yb); color=randint(color<<1)-color; color=color+(get_pixel(xa,ya)+get_pixel(xb,yb)+1)>>1; if (color<1) color=1; else if (color>255) color=255; if ((get_pixel(x,y)==0)) plot (x,y,color); } void Sub_Divide (int x1,int y1,int x2,int y2) { int x,y; unsigned char color; if (!((x2-x1<2)&&(y2-y1<2))) { x=(x1+x2)>>1; y=(y1+y2)>>1; New_Col (x1,y1,x,y1,x2,y1); New_Col (x2,y1,x2,y,x2,y2); New_Col (x1,y2,x,y2,x2,y2); New_Col (x1,y1,x1,y,x1,y2); color=(get_pixel(x1,y1)+get_pixel(x2,y1)+get_pixel(x2,y2)+get_pix el (x1,y2)+2)>>2; plot (x,y,color); Sub_Divide (x1,y1,x,y); Sub_Divide (x,y1,x2,y); Sub_Divide (x,y,x2,y2); Sub_Divide (x1,y,x,y2); } } main () { int x,y; x=320;y=200; Set_Graphics_Mode (x,y); set_pattern (); plot (0,0,randint(254)+1); plot (x-1,0,randint(254)+1); plot (x-1,y-1,randint(254)+1); plot (0,y-1,randint(254)+1); Sub_Divide (0,0,x-1,y-1); getch(); Set_Mode (0x03); }
/
本文档为【【精品】如何在WIN-TC中或TC++30中把一张BMP格式的图片显示出来】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。 本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。 网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。

历史搜索

    清空历史搜索