2MFCbmp图片读取保存Word格式.docx
《2MFCbmp图片读取保存Word格式.docx》由会员分享,可在线阅读,更多相关《2MFCbmp图片读取保存Word格式.docx(13页珍藏版)》请在冰豆网上搜索。
![2MFCbmp图片读取保存Word格式.docx](https://file1.bdocx.com/fileroot1/2023-2/5/fb124293-64e5-41de-96bd-b8e9d7e87305/fb124293-64e5-41de-96bd-b8e9d7e873051.gif)
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;
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中添加函数:
c.添加代码:
//************************写入bmp格式图片过程***************************//
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);
bfh.bfSize,sizeof(DWORD),1,fp);
bfh.bfReserved1,sizeof(WORD),1,fp);
bfh.bfReserved2,sizeof(WORD),1,fp);
bfh.bfOffBits,sizeof(DWORD),1,fp);
m_nSize=bfh.bfSize;
//图像文件的总字节数
/*判断是否是bmp格式图片'
BM'
*/
if(bfh.bfType!
=0x4d42){AfxMessageBox("
不是BMP格式图片!
}
/*读取信息头*/
/*解决BMP格式倒置的方法fread(&
bih,sizeof(BITMAPINFOHEADER),1,fp);
bih.biSize,sizeof(DWORD),1,fp);
bih.biWidth,sizeof(LONG),1,fp);
bih.biHeight,sizeof(LONG),1,fp);
bih.biPlanes,sizeof(WORD),1,fp);
bih.biBitCount,sizeof(WORD),1,fp);
bih.biCompression,sizeof(DWORD),1,fp);
bih.biSizeImage,sizeof(DWORD),1,fp);
bih.biXPelsPerMeter,sizeof(LONG),1,fp);
bih.biYPelsPerMeter,sizeof(LONG),1,fp);
bih.biClrUsed,sizeof(DWORD),1,fp);
bih.biClrImportant,sizeof(DWORD),1,fp);
if(bih.biSize!
=sizeof(bih)){AfxMessageBox("
本结构所占用字节数出现错误"
/*位图压缩类型:
必须是0(不压缩)、1(BI_RLE8压缩类型)、2(BI_RLE压缩类型)之一*/
if(bih.biCompression==BI_RLE8||bih.biCompression==BI_RLE4)
{AfxMessageBox("
位图被压缩!
/*获取图像高宽和每个像素所占位数*/
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。
//******************文件保存*****************//
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("
图片保存成功"
第五步:
添加保存函数SaveBmp
添加函数原理同第三步添加Readbmp函数,在添加下列代码:
/*保存bmp格式图片写出图片的过程只处理24像素的图片该图片无调色板*/
SaveBmp(LPCTSTRlpFileName)
/*lpFileName为位图文件路径名*/
//AfxMessageBox(lpFileName);
FILE*fpo=fopen(BmpName,"
FILE*fpw=fopen(lpFileName,"
wb"
bfh,sizeof(BITMAPFILEHEADER),1,fpo);
bih,sizeof(BITMAPINFOHEADER),1,fpo);
fwrite(&
bfh,sizeof(BITMAPFILEHEADER),1,fpw);
bih,sizeof(BITMAPINFOHEADER),1,fpw);
/*malloc只能申请4字节的空间(未知)*/
fread(m_pImage,m_nImage,1,fpo);
fwrite(m_pImage,m_nImage,1,fpw);
fclose(fpo);
fclose(fpw);
第六步:
在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
StretchBlt(0,0,640,640,&
//显示大小横为640*640
b.在voidCPictureMapView:
OnDraw(CDC*pDC)函数中添加ReadBmp读取图片:
if(EntName.Compare(_T("
bmp"
))==0)//bmp格式
ReadBmp();
//图片信息保存如全局变量
ShowBitmap(pDC,BmpName);
//显示图片