用c语言读取并显示bmp图像

上传人:wuxin****2020 文档编号:142965858 上传时间:2022-08-25 格式:DOC 页数:38 大小:81.01KB
收藏 版权申诉 举报 下载
用c语言读取并显示bmp图像_第1页
第1页 / 共38页
用c语言读取并显示bmp图像_第2页
第2页 / 共38页
用c语言读取并显示bmp图像_第3页
第3页 / 共38页
资源描述:

《用c语言读取并显示bmp图像》由会员分享,可在线阅读,更多相关《用c语言读取并显示bmp图像(38页珍藏版)》请在装配图网上搜索。

1、如何在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 uns

2、igned 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

3、 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;

4、RGBQUAD; unsigned char PalReg17= 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,0; unsigned char StandardPal48= 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 1616= 0,23

5、5,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

6、,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

7、,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,1

8、04,153,89,165,101,149,85, ; unsigned char ColorTable222= 0,12,10,14,9,13,11,15; unsigned char ColorMap2563; 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 SetD

9、acReg(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.BMPn); exit(1); ShowBmp(argv1); /* 根据图像文件名,读取图像内容并利用抖动技术进行显示 */ int ShowBmp(char *FileName) FILE *Fp; BITMAPFILEHEA

10、DER FileHead; BITMAPINFOHEADER InfoHead; RGBQUAD RGB; int N, W,Y,X,C,Color; unsigned char Buffer4096; 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(BITMAPINF

11、OHEADER),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=480;Y-) fread(Buffer,sizeof(unsigned

12、 char),W,Fp); for(;Y0;Y-) fread(Buffer,sizeof(unsigned char),W,Fp); for (X=0;XInfoHead.biWidth & X639;Y-) fread(Buffer,sizeof(unsigned char),W,Fp); for(;Y=0;Y-) fread(Buffer,sizeof(unsigned char),W,Fp); for(X=0;XInfoHead.biWidth & XL(unsigned int)G*256/255L(unsigned int)B*256/255L); void SetVideoMod

13、e(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*)Da

14、cReg); _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上看见吴进

15、写的TC的16色BMP闪电显示(66k)的代码,发现写的的确不错,而且绝对能在TC的initgraph()初始化的BGI模式下使用。美中不足是会产生中间文件。后来想了一下,干脆就使用那个中间文件,用程序把BMP转换成中间文件,直接用putimage输出不就好了。说到这里,可能大家还不能明白,不要紧下面我慢慢说起。(一)吴进的TC的16色BMP闪电显示TurboC2.0图形模式下显示BMP位图的高速方法,不同于一般的putpixel和line绘制的方法,速度之快令你感觉不到显示的过程,而且绝对能在TC的initgraph()初始化的BGI模式下使用。/*程序设计:吴进*/*注意:编译程序时内存模

16、式必需为Large以上模式*/#includestdio.h#includedir.h#includedos.h#includegraphics.hchar*malloc();/*malloc转换*/charbmp_to_dat(char*bmp,char*dat)/*将16色BMP文件转换为可以用putimage输出的格式,bmp为原BMP文件,dat为转化文件*/unsignedcharc8,scan_times,scan_pixs;unsignedcharworkpos;inti,j,k,n,nowpos,iw,ih;staticintcolor16=0,4,2,6,1,5,3,7,8,

17、12,10,14,9,13,11,15;unsignedcharworkline640,scanline640;FILE*fp,*targetfp;unionunsignedcharvalue;structunsignedcl:4;unsignedch: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&

18、iw640&ih480)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=0;n-

19、)/*解码4个位面*/for(i=0;iscan_times;i+)/*解码各编码单位*/workpos=0;for(k=0;k4;k+)/*分离出8个像素*/mycolor.value=scanlinei*4+k;ck*2=colormycolor.color.ch;ck*2+1=colormycolor.color.cl;for(k=0;kn&1)ff_fsize)=NULL)exit(0);n=0;while(!feof(fp)buffern=fgetc(fp);n+;for(n=0;n640&ih480)fclose(fp);fclose(targetfp);return(0);iw-

20、;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=0;n-)/*解码4个位面*/for(i=0;iscan_times;i+)/*解码各编码单位*/workpos=

21、0;for(k=0;k4;k+)/*分离出8个像素*/mycolor.value=scanlinei*4+k;ck*2=colormycolor.color.ch;ck*2+1=colormycolor.color.cl;for(k=0;kn&1)ff_fsize)=NULL)exit(0);putimage(x,y,buffer,COPY_PUT);/输出free(buffer);fclose(fp);如果你要频繁使用这张图片,那么就只在初始化时打开一次文件,内存不要释放,请读者自己写好了。(四)图片处理的问题16色图片由于颜色信息少,因此处理上就得很讲究了。使用xnview114gb.ex

22、e这个免费软件吧(本站可以下载),功能强大。另外的他的抖动处理,可以使16色图片显示更多信息。另外一个要点就是调色板的问题。使用ACDSEE等软件转换出来的16色,并不是标准的16色。他们使用了调色板。为了正确显示,建议使用WINDOWS自带的“画图”软件,进行处理。/*在DOS下显示16位色位图源程序*/#include#include#include#include#include#include#include#include#include#include#defineclosegrclosegraph/*位图文件头结构*/typedefstructintid;/*两字节的内容用来识别

23、位图的类型:BM:Windows3.1x,95,NT,BA:OS/2BitmapArrayCI:OS/2ColorIconCP:OS/2ColorPointerIC:OS/2IconPT:OS/2Pointer注:因为OS/2系统并没有被普及开,所以在编程时,你只需判断第一个标识BM就行*/longfilesize;/*用字节表示的整个文件的大小*/longreserved;/*保留,必须设置为0*/longdataoffset;/*从文件开始到位图数据开始之间的数据(bitmapdata)之间的偏移量*/longheadersize;/*位图信息头(BitmapInfoHeader)的长度,

24、用来描述位图的颜色、压缩方法等。下面的长度表示:28h-Windows3.1x,95,NT,0Ch-OS/21.xF0h-OS/22.x注:在Windows95、98、2000等操作系统中,位图信息头的长度并不一定是28h,因为微软已经制定出了新的BMP文件格式,其中的信息头结构变化比较大,长度加长。所以最好不要直接使用常数28h,而是应该从具体的文件中读取这个值。这样才能确保程序的兼容性。*/longwidth;/*位图的宽度,以象素为单位*/longheight;/*位图的高度,以象素为单位*/intPlanes;/*位图的位面数(注:该值将总是1)*/intPixe;/*每个象素的位数1

25、-单色位图(实际上可有两种颜色,缺省情况下是黑色和白色。你可以自己定义这两种颜色)4-16色位图8-256色位图16-16bit高彩色位图24-24bit真彩色位图32-32bit增强型真彩色位图*/longCompression;/*压缩说明:0-不压缩(使用BI_RGB表示)1-RLE8-使用8位RLE压缩方式(用BI_RLE8表示)2-RLE4-使用4位RLE压缩方式(用BI_RLE4表示)3-Bitfields-位域存放方式(用BI_BITFIELDS表示)*/longbmpDataSize;/*用字节数表示的位图数据的大小。该数必须是4的倍数*/longXPelsPerMeter;/

26、*用象素/米表示的水平分辨率*/longYPelsPerMeter;/*用象素/米表示的垂直分辨率*/longClrUsed;/*位图使用的颜色数。如8-比特/象素表示为100h或者256*/longClrImportant;/*指定重要的颜色数。当该域的值等于颜色数时(或者等于0时),表示所有颜色都一样重要*/BMPHEAD;BMPHEADBmpHead;charconvert16=0x0,0x4,0x2,0x6,0x1,0x5,0x3,0x7,0x8,0xc,0xa,0xe,0x9,0xd,0x3,0xf;/*BMP色彩与VGA色对照表*/unsignedchar*bmp_data;int

27、fp;/*BGI初始化函数*/voidinitgr(void)intgd=DETECT,gm=0;/*和gd=VGA,gm=VGAHI是同样效果*/registerbgidriver(EGAVGA_driver);/*注册BGI驱动后可以不需要.BGI文件的支持运行*/initgraph(&gd,&gm,);/*位图文件头读取函数*/intread_bmp_head(char*bmp_filename)if(fp=open(bmp_filename,O_RDONLY)=-1)/*打开位图文件*/printf(%s%s,bmp_filename,isnotfound.);return1;read

28、(fp,&BmpHead,sizeof(BMPHEAD);/*读取BMP文件的信息头*/if(BmpHead.id!=0x4d42)/*判断是否是BMP文件*/printf(%s%s,bmp_filename,isnotBMPfile);return1;return0;/*纠正宽度函数*/intcorrect_width(intwidth)intfactual_width;if(width%4=0&(width/4)%2=0);elsewhile(width%4!=0|(width/4)%2!=0)width+;factual_width=width;returnfactual_width;/

29、*读位图文件并显示函数*/voidput_bmp(char*bmpfile,intx,inty)intread_bmp_head_return,i,j,d=0,cn;bmp_data=(unsignedchar*)malloc(BmpHead.bmpDataSize*sizeof(unsignedchar);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);/*读取

30、颜色数据到缓冲区内*/cn=correct_width(BmpHead.width);for(i=BmpHead.height;i0;i-)for(j=0;j4);/*用高4位画1个点*/putpixel(x+j+,y+i,convertbmp_datad&0xf);/*用低4位画1个点*/d+;free(bmp_data);close(fp);/*主函数*/intmain(void)initgr();put_bmp(pix.bmp,320,240);getch();closegr();return0;/*这是上面程序的一个应用XPWIN2000可以不用再驱动鼠标了*/#includeConi

31、o.h#include#include#includegraphics.h#defineclosegrclosegraphunionREGSregs;voidinitgr(void)/*BGI初始化*/intgd=DETECT,gm=0;/*和gd=VGA,gm=VGAHI是同样效果*/registerbgidriver(EGAVGA_driver);/*注册BGI驱动后可以不需要.BGI文件的支持运行*/initgraph(&gd,&gm,);intinitmouse(intxmin,intxmax,intymin,intymax)intretcode;regs.x.ax=0;int86(0

32、x33,s,s);retcode=regs.x.ax;if(retcode=0)/*ax=0安装失败*/return0;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);/*设置垂直位置最大最小值*/returnretcode;intread(int*mx,int*my,int*mbutt)/*对鼠标的位置和按键状态函数*/intx0=*mx,y0=*my,buto=0;intxnew

33、,ynew;doregs.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(*mbutt217)*mx=xnew;*my=ynew;return1;/*右键按下*/elseif(*mbutt7)*mx=xnew;*my=ynew;return-1;/*左键按下*/else*mx=xnew;*my=ynew;return0;/*无键按下*/voidcursor(intx,inty,ch

34、ar*pic)/*画鼠标*/put_bmp(pic,x,y);intmouse_move(int*x,int*y,int*button)intx0=*x,y0=*y,mouse_button;mouse_button=read(x,y,button);cursor(x0,y0,pix.bmp);cursor(*x,*y,pix.bmp);returnmouse_button;intmouse_bound(int*x,int*y,intm1,intn1,intm2)if(m1*x&*xm2)if(n1*y&*yn1+20)return0;return1;/*把上面的函数加进来*/intmain(

35、void)intinit_mouse_x=320,init_mouse_y=240,buttons,mouse_button,bound_betton;intbound_x,bound_y;initgr();/*BGI初始化*/if(initmouse(0,639,0,479)=0)/*鼠标初始化*/*未安装鼠标处理*/exit(1);elsecursor(init_mouse_x,init_mouse_y,pix.bmp);domouse_button=mouse_move(&init_mouse_x,&init_mouse_y,&buttons);bound_x=init_mouse_x;

36、bound_y=init_mouse_y;if(mouse_button=-1)bound_betton=mouse_bound(&bound_x,&bound_y,300,390,340);if(bound_betton=0)break;while(1);closegr();/*恢复TEXT屏幕模式*/return0;近来,图像功能在计算机上的应用十分广泛,一种方便快捷而实用的方法是首先利用图像扫描仪将图像数据自动生成并存入计算机,再利用Windows的PAINTBRUH功能进行加工修改,成为独立的图像文件。但是,仍然有一个问题:PAINTBRUH软件只能在Windows环境下运行。因此要显

37、示一幅图像(.MSP位图、.BMP位图、PCX位图),也要运行庞大的Windows,显然不方便。为此,笔者编写了一个BMP位图文件直接显示在屏幕上的程序。利用TurboC位图格式,将BMP格式进行转换,实现了这一功能。一、TurboC位图格式Borlond公司的TurboC是目前在微机上最为流行的C语言版本。它为软件开发者提供了丰富的屏幕操作与图形功能函数。其中getimage()函数用于将屏幕内的某矩形区域复制到内存缓冲区,putimage()函数将内存缓冲区中的内容再复制到屏幕上。但由于图像事先还没有出现在屏幕上,所以,不能使用getimage()函数填写供putimage()函数显示的内

38、存图像数据。不过可以把图像数据按getimage()函数产生的格式填于内存缓冲区中,然后调用putimage()函数,显示内存缓冲区图像,下面分析getimage()函数产生的格式:getimage(intletf,inttop,intnight,intbottm,*buf)其中,left,top矩形区域左上角坐标(x,y)。right,bottom矩形区域右上角坐标(x,y)。*buf指向存储屏幕数据的内存指针。在内存中,图像数据是按行存放的。头两个字节为图像的宽度,接下去两个字节为图像的高度(均为低字节在前,高字节在后)。后面是真正的图像数据,它以图像的宽度为单位,先是图像的第一行第三位面

39、的内容,然后是第一行第二位面的内容;第一行第一位面的内容;第一行第零位面的内容。第一行完后,接第二行的四个位面,第三行的四个位面等等。当屏幕状态为16色时,则需4个彩色页面。这时,如果图像的宽度为8的整数倍时,则每行所需的字节数为:number=(right-left+8)18*4如果图像的宽度不为8的倍数据时,则number=(ceil(right-left)/8)*4)其中,ceil(righ-left)8为取大于(right-left)/8的最小整数则图像数据所需字节总数为:number*(bottom-top+1)则所需内存缓冲区字节总数为:6+number*(bottom-top+1

40、)这是因为头四个字节存放图像的宽和高,而缓冲区最后2个字节无意义,可以填零。T5S04700.GIF;图1这样,每行每页面的字节数为:p=number/4如图1所示(设宽、高为1616)其中,图像的真正数据在每个页面的前m列,即:当宽度为8的倍数据时,m=P-1,此时每页面的最后一列可为零。而当宽度不为8的倍数时,m=P。结合图1m=2,即数据在每页面的前2列。二、BMP位图格式MSWindows的.BMP图像文件可以表示单色或直至24位的彩色图像,.BMP文件是与设备无关的。.BMP文件分为文件首部和文件体两部分。文件首部描述文件和图像的有关参数和彩色表,主体是图像的位图数据。.BMP文件的格式如表1所示。T5S04701.GIF;表1BMP文件的格式T5S04702.GIF;表2BMP与VGA彩色编码对照.BMP文件的文件体记录图像的位图数据。从图像的左下角开

展开阅读全文
温馨提示:
1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
2: 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
3.本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
关于我们 - 网站声明 - 网站地图 - 资源地图 - 友情链接 - 网站客服 - 联系我们

copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!