2MFCbmp图片读取保存.docx

上传人:b****1 文档编号:2796577 上传时间:2023-05-04 格式:DOCX 页数:13 大小:79.32KB
下载 相关 举报
2MFCbmp图片读取保存.docx_第1页
第1页 / 共13页
2MFCbmp图片读取保存.docx_第2页
第2页 / 共13页
2MFCbmp图片读取保存.docx_第3页
第3页 / 共13页
2MFCbmp图片读取保存.docx_第4页
第4页 / 共13页
2MFCbmp图片读取保存.docx_第5页
第5页 / 共13页
2MFCbmp图片读取保存.docx_第6页
第6页 / 共13页
2MFCbmp图片读取保存.docx_第7页
第7页 / 共13页
2MFCbmp图片读取保存.docx_第8页
第8页 / 共13页
2MFCbmp图片读取保存.docx_第9页
第9页 / 共13页
2MFCbmp图片读取保存.docx_第10页
第10页 / 共13页
2MFCbmp图片读取保存.docx_第11页
第11页 / 共13页
2MFCbmp图片读取保存.docx_第12页
第12页 / 共13页
2MFCbmp图片读取保存.docx_第13页
第13页 / 共13页
亲,该文档总共13页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

2MFCbmp图片读取保存.docx

《2MFCbmp图片读取保存.docx》由会员分享,可在线阅读,更多相关《2MFCbmp图片读取保存.docx(13页珍藏版)》请在冰点文库上搜索。

2MFCbmp图片读取保存.docx

2MFCbmp图片读取保存

第二课bmp图片格式解析

<一>.BMP格式定义

BMP文件格式是Windows操作系统推荐和支持的图像文件格式,是一种将内存或显示器的图像数据不经过压缩而直接按位存盘的文件格式,故称位图(bitmap),其扩展名为BMP。

BMP图像文件被分为4个部分:

a.位图文件头b.位图信息头c.颜色表d.位图数据

a.颜色表中RGBQUAD结构数据的个数有biBitCount来确定:

  当biBitCount=1,4,8时,分别有2,16,256个表项;

  当biBitCount=24时,没有颜色表项。

  位图信息头和颜色表组成位图信息,BITMAPINFO结构定义如下:

  typedefstructtagBITMAPINFO{

  BITMAPINFOHEADERbmiHeader;//位图信息头

  RGBQUADbmiColors[1];//颜色表

  }BITMAPINFO;

b.位图数据

  位图数据记录了位图的每一个像素值,记录顺序是在扫描行内是从左到右,扫描行之间是从下到上。

位图的一个像素值所占的字节数:

当biBitCount=1时,8个像素占1个字节;

  当biBitCount=4时,2个像素占1个字节;

  当biBitCount=8时,1个像素占1个字节;

  当biBitCount=24时,1个像素占3个字节;

  Windows规定一个扫描行所占的字节数必须是

  4的倍数(即以long为单位),不足的以0填充,

  biSizeImage=((((bi.biWidth*bi.biBitCount)+31)&~31)/8)*bi.biHeight。

 

<二>.BMP图片在MFC工程中的定义

存在2个未解问题:

a.bmp结构时我定义成系统自带的结构,否则会多2个字节在图片最后为CD;

b.在read中malloc只能申请4字节的空间,但fread(,m_nImage,)读入位图大小个。

第一步:

添加BMP信息文件头

文件—新建—创建ImageStruct.h—包含BMP格式的文件头部分的结构。

打开ImageStruct.h并添加代码:

重点注意:

1.bmp结构头必须定义成BITMAPFILEHEADER_不能定义成BITMAPFILEHEADER;

因为在MFC中已存在BITMAPFILEHEADER的定义,在定义成它会显示重复定义。

同时自己定义的在View.h和View.cpp中注意引用#include“ImageStruct.h”。

2.在后面的引用bmp结构时我定义成系统自带的结构:

BITMAPFILEHEADERbfh;

BITMAPINFOHEADERbih;

而不是BITMAPFILEHEADER_,因为MFC中用自带的定义图片头文件信息是正确的,但在位图信息块总会在文件最后多出2字节并默认为CD(0x16进制)。

原因可能是自定义的图片头文件少2字节,在后面补充了2字节。

(未知)

 

/*******************************************************/

/*BMP位图文件包括4部分:

*/

/*位图文件头结构BITMAPFILEHEADER*/

/*位图信息头结构BITMAPINFOHEADER*/

/*位图颜色表RGBQUAD*/

/*位图像素数据*/

/*******************************************************/

 

#ifndef_IMAGESTRUCT_

#define_IMAGESTRUCT_

/*14byteBMP文件头含有BMP文件的类型、大小、位图文件的保留字、位图数据距文件头的偏移量*/

typedefstructT_BITMAPFILEHEADER{

WORDbfType;//2byte位图文件的类型,必须为BM0x424d

DWORDbfSize;//4byte位图文件的大小,以字节为单位

WORDbfReserved1;//2byte位图文件保留字,必须为0

WORDbfReserved2;//2byte位图文件保留字,必须为0

DWORDbfOffBits;//4byte位图数据距文件头的偏移量(字节)

}BITMAPFILEHEADER_;

/*40byteBMP位图信息头用于说明位图的尺寸等信息*/

typedefstructT_BITMAPINFOHEADER{

DWORDbiSize;//本结构所占用字节数

LONGbiWidth;//位图的宽度,以像素为单位

LONGbiHeight;//位图的高度,以像素为单位

WORDbiPlanes;//目标设备的级别,必须为1

WORDbiBitCount;

//每个像素所需的位数,必须是1(双色)、4(16色)、8(256色)或24(真彩色)之一

DWORDbiCompression;

//位图压缩类型,必须是0(不压缩)1(BI_RLE8压缩类型)或2(BI_RLE压缩类型)之一

DWORDbiSizeImage;//位图的大小,以字节为单位

LONGbiXPelsPerMeter;//位图水平分辨率,每米像素数

LONGbiYPelsPerMeter;//位图垂直分辨率,每米像素数

DWORDbiClrUsed;//位图实际使用的颜色表中的颜色数

DWORDbiClrImportant;//位图显示过程中重要的颜色数

}BITMAPINFOHEADER_;

/*BMP位图颜色表*/

typedefstructT_RGBQUAD

{

BYTErgbBlue;//蓝色的亮度(值范围为0~255)

BYTErgbGreen;//绿色的亮度(值范围为0~255)

BYTErgbRed;//红色的亮度(值范围为0~255)

BYTErgbReserved;//保留,必须为0

}RGBQUAD_;

#endif

 

第二步:

在..View.h中添加共有成员变量和成员函数

1.找到..View.h头文件添加:

#include"ImageStruct.h"

2.在ClassCBmpDrawView:

publicCview中的public中添加成员变量函数:

public:

//用来保存bmp格式图片

boolSaveBmp(LPCSTRlpFileName);

//用来读取bmp图片

boolReadBmp();

//用来显示指定位图jpg、gif的函数

boolShowJpgGif(CDC*pDC,CStringstrPath,intx,inty);

//用来显示指定位图bmp的函数

voidShowBitmap(CDC*pDC,CStringBmpName);

/*CBitmapm_bitmaplin;创建临时位图对象进行处理*/

CBitmapm_bitmap;//创建位图对象

CStringEntName;//保存图像文件扩展名

CStringBmpName;//保存图像文件文件名

intm_nWidth;//图像实际宽度

intm_nHeight;//图像实际高度

intm_nDrawWidth;//图像显示宽度

intm_nDrawHeight;//图像显示高度

DWORDm_nImage;//图像数据的字节数只含位图DWORD相当于longint

DWORDm_nSize;//图像文件大小

intm_nLineByte;//图像一行所占字节数

intm_nBitCount;//图像每个像素所占位数

intm_nPalette;//位图实际使用的颜色表中的颜色数

/*注意:

信息头必须条用系统bmp的结构BITMAPFILEHEADER否则会多2字节*/

BITMAPFILEHEADERbfh;//全局变量文件头

BITMAPINFOHEADERbih;//全局变量信息头

RGBQUAD*m_pPal;//颜色表指针

BYTE*m_pImage;//读入图片数据后的指针BYTE相当于unsignedchar

virtual~CBmpDrawView();

第三步:

添加readbmp函数

添加函数的方法:

a.在View.h的public中直接添加函数boolReadBmp()像第二步中一样;然后在View.cpp中添加函数:

boolCBmpDrawView:

:

ReadBmp(){}。

b.选中ClassView区--选中View类右键--增加成员变量函数—函数类型为bool—函数名为ReadBmp()—函数Access为public。

程序会自动在View.cpp中添加函数:

boolCBmpDrawView:

:

ReadBmp(){}。

c.添加代码:

//************************写入bmp格式图片过程***************************//

boolCBmpDrawView:

:

ReadBmp()

{

FILE*fp=fopen(BmpName,"rb");//读取bmp图片BmpName为图片的绝对路径

if(fp==0){AfxMessageBox("无法打开文件!

",MB_OK,0);return0;}

/*读取文件头全局变量bfhBITMAPFILEHEADER定义在ImageStruct中*/

/*解决BMP格式倒置的方法(CSDN)fread(&bfh,sizeof(BITMAPFILEHEADER),1,fp);倒置*/

fread(&bfh.bfType,sizeof(WORD),1,fp);

fread(&bfh.bfSize,sizeof(DWORD),1,fp);

fread(&bfh.bfReserved1,sizeof(WORD),1,fp);

fread(&bfh.bfReserved2,sizeof(WORD),1,fp);

fread(&bfh.bfOffBits,sizeof(DWORD),1,fp);

m_nSize=bfh.bfSize;//图像文件的总字节数

/*判断是否是bmp格式图片'BM'*/

if(bfh.bfType!

=0x4d42){AfxMessageBox("不是BMP格式图片!

",MB_OK,0);return0;}

/*读取信息头*/

/*解决BMP格式倒置的方法fread(&bih,sizeof(BITMAPINFOHEADER),1,fp);倒置*/

fread(&bih.biSize,sizeof(DWORD),1,fp);

fread(&bih.biWidth,sizeof(LONG),1,fp);

fread(&bih.biHeight,sizeof(LONG),1,fp);

fread(&bih.biPlanes,sizeof(WORD),1,fp);

fread(&bih.biBitCount,sizeof(WORD),1,fp);

fread(&bih.biCompression,sizeof(DWORD),1,fp);

fread(&bih.biSizeImage,sizeof(DWORD),1,fp);

fread(&bih.biXPelsPerMeter,sizeof(LONG),1,fp);

fread(&bih.biYPelsPerMeter,sizeof(LONG),1,fp);

fread(&bih.biClrUsed,sizeof(DWORD),1,fp);

fread(&bih.biClrImportant,sizeof(DWORD),1,fp);

if(bih.biSize!

=sizeof(bih)){AfxMessageBox("本结构所占用字节数出现错误");return0;}

/*位图压缩类型:

必须是0(不压缩)、1(BI_RLE8压缩类型)、2(BI_RLE压缩类型)之一*/

if(bih.biCompression==BI_RLE8||bih.biCompression==BI_RLE4)

{AfxMessageBox("位图被压缩!

");return0;}

/*获取图像高宽和每个像素所占位数*/

m_nHeight=bih.biHeight;

m_nWidth=bih.biWidth;

m_nDrawHeight=bih.biHeight;

m_nDrawWidth=bih.biWidth;

m_nBitCount=bih.biBitCount;//每个像素所占位数

/*计算图像每行像素所占的字节数(必须是4字节的倍数)2种方法*/

//m_nLineByte=(m_nWidth*m_nBitCount/8+3)/4*4;

m_nLineByte=(m_nWidth*m_nBitCount+31)/32*4;

/*计算图片位图的大小长*宽*3为24位bmp位图大小3表示rgb*/

m_nImage=m_nLineByte*m_nHeight;

/*位图实际使用的颜色表中的颜色数biClrUsed注:

24位bmp不用改参数*/

m_nPalette=0;

if(bih.biClrUsed)m_nPalette=bih.biClrUsed;

/*申请位图空间大小为位图大小m_nImage*/

/*注意:

malloc只能申请4字节的空间(未知)但fread(,m_nImage,)读入位图大小个*/

m_pImage=(BYTE*)malloc(m_nImage);

fread(m_pImage,m_nImage,1,fp);

/*注意:

要关闭fp*/

fclose(fp);

returntrue;

}

 

第四步:

添加保存menu控件和函数

a.查看--建立类导向(Ctrl+W)--CpictureXSView(类名)--ID_FILE_SAVE(IDs列表)--COMMAND(Messages列表)--默认成员函数名为OnFileSave

--MemberFunctions(成员函数)中双击该函数进入函数编辑。

b.注意:

Ctrl+W把另存为也设置成与保存相同的函数。

ID_FILE_SAVE_AS--COMMAN--函数OnFileSaveAs改名为OnFileSave。

c.添加代码:

//******************文件保存*****************//

voidCBmpDrawView:

:

OnFileSave()

{

//TODO:

Addyourcommandhandlercodehere

CStringfilter;

filter="所有文件(*.*)|*.bmp;*.jpg;*.gif;*.tiff|BMP(*.bmp)|*.bmp|JPG(*.jpg)|*.jpg|GIF(*.gif)|*.gif|TIFF(*.tiff)|*.tiff||";

/*重点:

1-文件打开0-文件保存*/

CFileDialogdlg(0,NULL,NULL,OFN_HIDEREADONLY,filter,NULL);//产生保存对话框

/*按下确定按钮*/

if(dlg.DoModal()==IDOK)

{

CStringstr;

CStringstrName;

CStringfilename;

str=dlg.GetPathName();//获取文件的路径

filename=dlg.GetFileTitle();//获取文件名

intnFilterIndex=dlg.m_ofn.nFilterIndex;

if(nFilterIndex==2)//当用户选择文件过滤器为".BMP"时

{

str=str+".bmp";//自动加扩展名.bmp

SaveBmp(str);//保存bmp图片就是一个写出图片的过程

AfxMessageBox("图片保存成功",MB_OK,0);

}

}

}

 

第五步:

添加保存函数SaveBmp

添加函数原理同第三步添加Readbmp函数,在添加下列代码:

/*保存bmp格式图片写出图片的过程只处理24像素的图片该图片无调色板*/

boolCBmpDrawView:

:

SaveBmp(LPCTSTRlpFileName)

{

/*lpFileName为位图文件路径名*/

//AfxMessageBox(lpFileName);

FILE*fpo=fopen(BmpName,"rb");

FILE*fpw=fopen(lpFileName,"wb");

fread(&bfh,sizeof(BITMAPFILEHEADER),1,fpo);

fread(&bih,sizeof(BITMAPINFOHEADER),1,fpo);

fwrite(&bfh,sizeof(BITMAPFILEHEADER),1,fpw);

fwrite(&bih,sizeof(BITMAPINFOHEADER),1,fpw);

/*malloc只能申请4字节的空间(未知)*/

m_pImage=(BYTE*)malloc(m_nImage);

fread(m_pImage,m_nImage,1,fpo);

fwrite(m_pImage,m_nImage,1,fpw);

fclose(fpo);

fclose(fpw);

returntrue;

}

 

第六步:

在word1中的修改

a.在voidCPictureMapView:

:

ShowBitmap(CDC*pDC,CStringBmpName)中实现图片可以压缩伸展显示的功能:

//***************************************************************************//

/*图片显示调用函数BitBlt变成StretchBlt*/

//pDC->BitBlt(0,0,m_bmp.bmWidth,m_bmp.bmHeight,&dcBmp,0,0,SRCCOPY);

if(m_nDrawWidth<650&&m_nDrawHeight<650)

pDC->StretchBlt(0,0,m_nDrawWidth,m_nDrawHeight,&dcBmp,0,0,m_bmp.bmWidth,m_bmp.bmHeight,SRCCOPY);//显示原图

else

pDC->StretchBlt(0,0,640,640,&dcBmp,0,0,m_bmp.bmWidth,m_bmp.bmHeight,SRCCOPY);

//显示大小横为640*640

//***************************************************************************//

b.在voidCPictureMapView:

:

OnDraw(CDC*pDC)函数中添加ReadBmp读取图片:

//***************************************************************************//

if(EntName.Compare(_T("bmp"))==0)//bmp格式

{

ReadBmp();//图片信息保存如全局变量

ShowBitmap(pDC,BmpName);//显示图片

}

//***************************************************************************//

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > PPT模板 > 商务科技

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2