2.MFC-bmp图片读取保存
MFC中显示.bmp格式的位图
MFC中显⽰.bmp格式的位图最近在看VisualC++ 图像处理的书籍,表⽰⼀直在从基础做起,今天就记录⼀个简单功能的实现,显⽰.bmp格式的位图。
⾸先需要理解的是窗⼝创建的过程包括两个步骤:⾸先擦除窗⼝的背景,然后在对窗⼝进⾏重新绘制。
⼀般⽽⾔,对于单⽂档或多⽂档的MFC程序,显⽰图像的代码要放在OnDraw函数之中。
刚刚说过,窗⼝重绘时,要先将窗⼝的背景擦除,也就是发送WM_ERASEBKGND消息,然后⽤OnEraseBkgnd()函数处理这个消息,所以我们的显⽰图像的代码也可以放在这个函数之中。
当然,这⾥只是为了实现显⽰位图这⼀个功能,在实际⼯程中,要根据实际情况,选择代码放置的地⽅。
下⾯先给出代码,然后⼀⾏⼀⾏地详细解释:BOOL CLoadBitmapView::OnEraseBkgnd(CDC* pDC){// TODO: 在此添加消息处理程序代码和/或调⽤默认值//return FALSE;HBITMAP hBit;hBit=(HBITMAP) LoadImage(NULL,_T("D:\\Axing.bmp"),IMAGE_BITMAP,0,0,LR_LOADFROMFILE|LR_CREATEDIBSECTION); //载⼊图像CBitmap cBit;cBit.Attach(hBit);CDC MemDC;MemDC.CreateCompatibleDC(pDC); //创建与当前设备描述表相适应的内存DCBITMAP bitmap;cBit.GetBitmap(&bitmap);CBitmap *oldBit;oldBit=MemDC.SelectObject(&cBit);CRect rect;GetClientRect(&rect);pDC->BitBlt(100,100,rect.Width()/2.5,rect.Height(),&MemDC,0,0,SRCCOPY);return TRUE;//return CView::OnEraseBkgnd(pDC);}⾸先来解释⼀下HBITMAP、CBitmap、BITMAP三者之间的关系。
VC环境下读取显示.bmp图像方法
VC环境下读取显示.bmp图像方法总结显示bmp图像的方法,列出四种显示方法。
1 通过SetPixel()函数画出每个像素点来显示图像。
2 通过读取位图资源中bmp资源显示图像。
3 通过读取本地文件,利用位图结构信息,定义HGLOBAL,再采用固定的显示方式显示位图。
4 通过读取本地文件,利用位图结构信息,定义buffer,再采用SetDIBitsT oDevice()函数。
下面分别对这四种方法进行详细描述:首先新建VC工程ShowBmpImage->MFC->单文档模式。
将显示的操作都是放在CShowBmpImageView下进行的,并且没有定义成员变量。
1 第一种方法通过SetPixelShow()函数循环画出每个像素点,从而显示图像。
操作如下:增加成员函数SetPixelShow(),编辑代码如下:int x,y; //定义像素位置CClientDC dc(this); //获取dc,也可以用CDC *pDCfor(x=0;x<200;x++)for(y=0;y<200;y++)dc.SetPixel(x,y,RGB(x,y,255)); //画一个像素点,RGB是颜色调用函数后,显示的是一幅彩色图像,可以根据需要改变RGB的值来显示一幅完整的图像。
2 第二种方法通过读取位图资源中的位图显示图像,选择菜单栏->插入->资源,弹出对话框,选择导入按钮,将文件类型改成所有文件,选择想要显示bmp位图,导入。
这样工程的资源位图中,导入的位图默认的ID 是IDB_BITMAP1。
而显示这种位图有一个固定的显示模式,非常方便。
方法如下:a 定义一个CBitmap对象,使其加载位图资源。
b 定义一个CDC对象,用于装载位图;使其创建兼容DC,相当于初始化;与CBitmap对象关联起来,相当于获取位图。
c 定义BITMAP对象,使其与CBitmap对象绑定,可以获取宽度和高度。
MFC 读取并显示图片和彩色转灰度
By侯海艳(UCAS)
关于MFC读取BMP图片,相信对于很多初学者都是一头雾水,找不着头绪。那么就让我浅浅地说一说到底怎么样读取并显示BMP图片吧。因为我也是初学,摸索学习了四五天,由于有些MFC基础,因此大概理清了MFC读取图片的机理。说的不对请提出宝贵建议,高手请绕道。
C++的学习难就难在指针上面,我们必须很好地了解数据的存储方式和指针的基本知识。一般来说,数据存储在内存中是以内存块的形式存储的,即给变量分配一定大小的空间,这个空间就像书架一样,里面装满了一本一本的书,每本书就对应着一个数据单元。我们定义一个指针,指向这个内存块,指针的位置就在内存块的开头,即数据的第一个元素。当我们要获取后面的元素的时候就要移动指针获取。下面会具体说。
1.从新建MFC文档开始
新建MFC文档的时候,可以选择多文档类型,一般选择默认,但有一点需要注意,当新建这只到了第六步的时候,C*View类的Base Class要选择CScrollView,而不是默认的CView。如下图:Teeee是我随便命名的工程名
(旋转了90度)
这样打开文档就可以看到上图中有许多文件,我们所要编辑的主要是Doc.cpp、View.cpp和Header Files里面的Doc.h头文件。
if ( rowBytes!=pDoc->m_Width*pDoc->m_PxlBytes )
{
pBuf = new BYTE[pDoc->m_Height*rowBytes];
for (int i=0;i<pDoc->m_Height;i++ )
memcpy( pBuf+i*rowBytes,pDoc->pImgData+i*pDoc->m_Width*pDoc->m_PxlBytes,pDoc->m_Width*pDoc->m_PxlBytes );
MFC开发位图BitMap图像的读取与存储
[cpp]view plaincopy01. #include "BitMap.h"02. #include03. #include04. #include05. usingnamespace std;06. #define NULL 007.08. BitMap::BitMap(){};09. BitMap::~BitMap(){};10.11. //read bitmap info from a file12. bool BitMap::Read(char* fileName)13. {14. FILE *_f=fopen(fileName,"rb");//open file15. if(_f==NULL) returnfalse;16.17. fread(&fileHeader,sizeof(BITMAPFILEHEADER),1,_f);//read BITMAPFILEHEADER18.19. fread(&infoHeader,sizeof(BITMAPINFOHEADER),1,_f);//read BITMAPINFOHEADER20. width_p=infoHeader.biWidth;21. height_p=infoHeader.biHeight;22. bitCount=infoHeader.biBitCount;23.24. if(bitCount==8)//if colorTable exist,read colorTable25. {26. colorTable=new RGBQUAD[256];27. fread(&colorTable,sizeof(RGBQUAD),256,_f);28. }29.30. dataBuf=new unsigned char[infoHeader.biSizeImage];//read image data31. fread(dataBuf,1,infoHeader.biSizeImage,_f);32.33. fclose(_f);//close file34. returntrue;35. }36.37. //write bitmap info to a file38. bool BitMap::Write(char * _fileName)39. {40. FILE* f=fopen(_fileName,"wb");//create or open file to be written41. if(f==NULL) returnfalse;42.43. int colorTableSize=0;//if bitcount is 24, there is no color table.44. if(bitCount==8)//if bitcount is 8 ,the size of color table is 256*4,4B is the size of RGBQUAD.45. colorTableSize=sizeof(RGBQUAD)*256;46.47. int headerSize=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+ colorTableSize;//the size of the header of bmp file.48. int lineSize=(width_p*bitCount/8+3)/4*4;//the size of each line in bmp file.49. int dataSize=lineSize*height_p;//the size of the image data of bmp file.50.51. fileHeader.bfType=0x4D42;//set the attribute of BITMAPFILEHEADER52. fileHeader.bfSize=headerSize+dataSize;53. fileHeader.bfReserved1=0;54. fileHeader.bfReserved2=0;55. fileHeader.bfOffBits=headerSize;56.57. infoHeader.biSize=40;//set the attribute of BITMAPINFOHEADER58. infoHeader.biWidth=width_p;59. infoHeader.biHeight=height_p;60. infoHeader.biPlanes=1;61. infoHeader.biBitCount=bitCount;62. infoHeader.biCompression=0;63. infoHeader.biSizeImage=dataSize;64. infoHeader.biClrImportant=0;65. infoHeader.biXPelsPerMeter=0;66. infoHeader.biYPelsPerMeter=0;67.68. fwrite(&fileHeader,sizeof(BITMAPFILEHEADER),1,f);//write the data of BITFILEHEADER to bmp file69. fwrite(&infoHeader,sizeof(BITMAPINFOHEADER),1,f);//write the data of BITINFOHEADER to bmp file70. if(bitCount==8)//if color table exists,write the data of color table to bmp file71. {72. colorTable=new RGBQUAD[256];73. fwrite(&colorTable,sizeof(RGBQUAD),256,f);74. }75. fwrite(dataBuf,1,dataSize,f);//write the image data to bmp file76.77. fclose(f);//data writting is finished,close the bmp file.78. return true;79. }程序入口:[cpp]view plaincopy01. void main()02. {03. BitMap* bm=new BitMap();04. bm->Read("nv.BMP");05. bm->Write("nvnew.bmp");06. delete bm;07. }。
MFC窗口程序添加bmp图片
MFC窗口程序添加bmp图片2010-11-29 22:26最近重新开始学习MFC。
想往窗口里画张图,折腾了一个多小时。
(唉,欲善其事,先利其器.....我资料太少了)以后写点东西就往这里传了,一来方便以后自己参阅,另一方面希望帮到遇到同样问题的兄弟姐妹们。
参考资料 MFC windows 编程(第二版)Step 1 :新建一个空白窗口 VC 6.0 工程:Win32 Application添加头文件:lonewolf_mm.h 名字取个你喜欢的把下面的代码拷进去,没关系,编程一开始都是抄别人的 : )/****************************************************************************** * File Name : lonewolf_mm.h* Description :* Author : lonewolf******************************************************************************/class CMyApp :public CWinApp{public:virtual BOOL InitInstance();};class CMainWindow : public CFrameWnd{public:CMainWindow();protected:afx_msg void OnPaint();DECLARE_MESSAGE_MAP()};///////////////////////////////////////////////// file end//////////////////////////////////////////////////////////////////////////按下来是源文件了,同样的新建一个cpp,把下面的代码拷进去。
MFC界面保存实现
/ghevinn/article/details/28269743将屏幕和MFC程序界面保存成bmp格式图片保存分类:c++专区MFC客户端2014-06-03 16:39 915人阅读评论(1) 收藏举报将屏幕保存为图片,使用vs2008编译通过。
#include "stdafx.h"#include <windows.h>#include <atlimage.h>int __stdcall WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd){HWND hwnd = ::GetDesktopWindow();HDC hDC = ::GetDC(hwnd);//获取屏幕DCRECT rect;::GetClientRect(hwnd, &rect);//获取屏幕大小HDC hDCMem = ::CreateCompatibleDC(hDC);//创建兼容DCHBITMAP hBitMap = ::CreateCompatibleBitmap(hDC, rect.right, rect.bottom);//创建兼容位图HBITMAP hOldMap = (HBITMAP)::SelectObject(hDCMem, hBitMap);//将位图选入DC,并保存返回值::BitBlt(hDCMem, 0, 0, rect.right, rect.bottom, hDC, 0, 0, SRCCOPY);//将屏幕DC的图象复制到内存DC中CImage image;image.Attach(hBitMap);image.Save(_T("c://B.jpg"));//如果文件后缀为.bmp,则保存为为bmp格式image.Detach();::SelectObject(hDCMem, hOldMap);//选入上次的返回值//释放::DeleteObject(hBitMap);::DeleteDC(hDCMem);::DeleteDC(hDC);return 0;}将当前MFC程序(这里是单文档程序)保存为图片,使用vs2005。
图像处理Bmp文件存储顺序
读写Bmp文件的方法步骤:读:1.读方式打开文件2.读入BITMAPFILEHEADER结构3.读入BITMAPINFOHEADER结构4.读入颜色表RGBQUAD结构5.读入位图数据6.关闭文件写:1.写方式打开文件2.填写BITMAPFILEHEADER结构并写入文件3.写入BITMAPINFHEADER结构并写入文件4.写颜色表进文件5.写位图数据进文件6.关闭文件①:位图文件头BITMAPFILEHEADER: (14字节)bfType :位图文件类型(0x4D42)bfSize :位图文件大小bfReserved1: Windows保留字1bfReserved2: Windows保留字2bfOffBits: 从文件头到实际位图数据的偏移字节数=文件头+ 信息头+调色板长度。
②:位图信息头(40字节)biSize: 本结构长度为40字节biWidth: 位图宽度,(像素为单位)biHeight: 位图的高度,(像素为单位)biPlanes: 设为1biCount: 位深度biCompression: 为0:不压缩;1:8位压缩;2:4位压缩。
biSizeImage:实际的位图数据占用的字节数biXPelsPerMeter:水平分辨率(像素/米)biYPelPerMeter: 垂直分辨率(像素/米)biClrCount:位图实际用到的颜色数(为0时,颜色数为2的biBitCount次幂)biClrImportant:位图显示过程中重要的颜色数(0:都是重要的)③:颜色表(4字节)rgbBlue:蓝色分量rgbGreen:绿色分量rgbRed: 红色分量rgbReserved:保留字节颜色表的大小:二值图像:大小=2*sizeof(RGBQUAD)=88位灰度图像:大小= 256*sizeof(RGBQUAD)= 102424位真彩色图像无颜色表④位图数据8位灰度图像ColorTablesize = 1024;lineByte =(bmpWidth * biBitCount / 8 + 3)/4 *4;1.申请位图文件头结构变量,并填写文件头信息BITMAPFILEHEADER fileHeader;fileHead.bfType = 0x4D42; //bmp类型//bfSize是图像文件4个组成部分之和fileHeader.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAOINFOHEADER) + ColorTablesize + lineByte*Height;fileHeader.bfReserved1 = 0;fileHeader.bfReserved2 = 0;//bfOffBits是图像文件前3部分所需空间之和fileHead.bfOffBits = 54 + ColorTablesize;2.申请位图信息头结构变量,填写信息头信息BITMAPINFOHEADER head;head.biBitCount = biBitCount;head.biClrImportant = 0;head.biClrUsed = 0;head.biCompression = 0;head.biHeight = height;head.biSize = 40;head.biSizeImage = lineByte * height;head.biWidth = width;head.biXPelsPerMeter = 0;head.biYPelsPerMete = 0;3.写灰度图像的颜色表4.写位图数据进文件调色板句柄HPALETTE文件头指针LPBITMAFILEHEADER : m_lpDib信息头指针LPBITMAPINFOHEADER :m_lpBmpInfoHead 颜色表LPRGBQUAD : m_lpColorTable 信息指针LPBITMAPINFO :m_lpBmpInfo图像数据指针:m_pImgData (包括:信息头指针和颜色表)1读入一幅图像(即打开操作):将四部分都考虑进去(1,2,3,4);2写入一幅图像(即保存操作):将四部分都考虑进去(1,2,3,4)3显示一幅图像:只需将3部分考虑进去(2,3,4)4 处理一幅图像:只需将3部分考虑进去(2,3,4)位图显示和数据处理:将(位图信息头、颜色表)即:信息指针内容,位图数据指针依次写入,并进行操作。
MFC对话框打开一幅图片并在picture显示和图片保存
学了MFC一段时间后,试着要用对话框打开一幅bmp图像并保存,结果发现网上这些资料太少了,而且有的也讲不清,讲不全,所以自己磕磕碰碰捣鼓了好久,期间也谢谢各位大神的指导,现在我终于完成,特意写出来与大家分享,各位菜鸟共勉。
一、首先要先了解bmp位图结构可以去看看,内容不多但是够看,也容易懂二、了解位图的显示函数SetStretchBltMode()StretchDIBits()具体函数介绍自己百度一下,我就不多说了三、开始做啦1、新建一个MFC对话框文档默认其他设置,点击完成后会出现这个界面&在按钮上单击鼠标右键,在弹出的列表中选择属性把标题改为读取图片再添加一个按钮,把ID改为IDC_SAVE,标题改为保存图片在控件中选择图像,然后在对话框画一个大小适宜的矩形框,在选中对话框点击右键,选择属性,把ID改为IDC_PICTURE回到对话框界面,双击读取图片按钮,这时会弹出一个对话框,点确定然后就会跳到关联函数这边了先把CDialog::OnOK();注释起来,这个是点击按钮后对话框就会关闭的函数【然后在MP", NULL, NULL,"位图文件(*.BMP)|*.bmp;*.BMP|",this);CFile bmpFile;pp文件头处添加BITMAPINFO* pBmpInfo;MP", NULL, NULL,"位图文件(*.BMP)|*.bmp;*.BMP|");if (!() == IDC_SAVE) return;strFileName = ();if (strFileName, CFile::modeCreate | CFile::modeReadWrite) == 0) return ;Widthbytes = (iBmpWidth*3+3)/4*4;//位图对齐,确保为4的倍数/* BITMAPFILEHEADER结构填写 */`= 0x4d42;=sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);= + Widthbytes *iBmpHeight;= 0;= 0;/* BITMAPINFOHEADER结构填写 */= sizeof(BITMAPINFOHEADER);= iBmpWidth;=iBmpHeight;= 1;\= 24;//24位= BI_RGB;=0;= 0;= 0;= 0;= 0;(&bmpf,sizeof(bmpf));//写文件头;(&bmpi,sizeof(bmpi));//写信息头;|(pBmpData,Widthbytes*iBmpHeight);//写图像数据信息;();OK全部完成了,编译运行一下,点击打开图片按钮就能显示图片了呵呵,写得不够专业,还望大家不吝赐教。
MFC打开和保存一幅bmp图片---编程流程
MFC打开和保存一幅bmp图片---编程流程打开一幅图片1.新建一个多文档的MFC应用程序.2.在_Doc.h文件的C_Doc类中增加如下成员变量;public:int numquad; //调色板数int flagOpen; //标志是否打开bmpBITMAPINFO* pbi; //记录图像细节BYTE* lpbuf; //图像数据RGBQUAD* quad; //调色板BITMAPFILEHEADER bf;//文件头BITMAPINFOHEADER bi; //信息头3.修改”打开”菜单项的响应函数;a.找到菜单资源b.在”打开”菜单项建立类向导,页面设置如下:选择“Add function”,然后单击“Edit Code”编辑代码如下:void CZhbDoc::OnFileOpen(){// TODO: Add your command handler code hereLPCTSTR lpszFilter="BMP Files(*.bmp)|*.bmp|任何文件|*.*||";CFileDialogdlg(TRUE,lpszFilter,NULL,OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,lpszFilter,NULL);CString filepath;CFile file;//打开文件对话框if(dlg.DoModal()==IDOK){filepath=dlg.GetPathName();if(file.Open(filepath,CFile::modeRead|CFile::shareDenyNone,NULL)==0){//读取文件失败AfxMessageBox("无法打开文件!",MB_OK,0);return;}//读取文件头file.Read(&bf,sizeof(bf));//判断是否是BMP文件if(bf.bfType!=0x4d42)//'BM'{AfxMessageBox("非BMP文件!",MB_OK,0);return;}//判断文件是否损坏if(file.GetLength()!=bf.bfSize){AfxMessageBox("文件已损坏,请检查!",MB_OK,0);return;}//读文件信息头file.Read(&bi,sizeof(bi));//计算调色板数目numquad=0;if(bi.biBitCount<24){numquad=1<<bi.biBitCount;}//为图像信息pbi申请空间pbi=(BITMAPINFO*)HeapAlloc(GetProcessHeap(),0,sizeof(BITMAPINFOHEADER)+numquad*sizeof( RGBQUAD));memcpy(pbi,&bi,sizeof(bi));quad=(RGBQUAD*)((BYTE*)pbi+sizeof(BITMAPINFOHEADER));//读取调色板if(numquad!=0){file.Read(quad,sizeof(RGBQUAD)*numquad);}//为图像数据申请空间bi.biSizeImage=bf.bfSize-bf.bfOffBits;lpbuf=(BYTE*)HeapAlloc(GetProcessHeap(),0,bi.biSizeImage);//读取图像数据file.Read(lpbuf,bi.biSizeImage);//图像读取完毕,关闭文件,设置标志file.Close();flagOpen=1;}}4.在C_Veiw类中增加paint消息处理函数;a. 如下图:点击“add handler”,然后再点“edit existing”c.在处理函数里编写如下代码:void CZhbView::OnPaint(){CPaintDC dc(this); // device context for painting// TODO: Add your message handler code hereCZhbDoc* pDoc = GetDocument(); //得到文档指针,注意,文档的命名是与工程名有关的!!不同的程序不一样.ASSERT_VALID(pDoc);//是否已打开某个BMP文件if(pDoc->flagOpen==1){//这个函数显示DIBSetDIBitsToDevice(dc.m_hDC, //DIB将输出的设备描述表0, //设备描述表中位图输出起始逻辑x地址0, //设备描述表中位图输出起始逻辑x地址pDoc->bi.biWidth, //DIB的宽度pDoc->bi.biHeight, //DIB的高度0, //DIB开始读取输出的像素数据的x位置0, //DIB开始读取输出的像素数据的y位置0, //DIB中像素的水平行号,它对应lpBits内存缓冲区第一行数据 pDoc->bi.biHeight, //DIB的行数,对应包含在由lpBits所指内存缓冲区中的数据pDoc->lpbuf, //包含像素数据的内存缓冲区的指针pDoc->pbi, //指向初始化了的BITMAPINFO数据结构的指针,描述了位图的大小和色彩数据DIB_RGB_COLORS); //指定是显示的颜色}Invalidate(FALSE);// Do not call CView::OnPaint() for painting messages}保存一幅图片1.修改”另存为”菜单项的响应函数;a找到菜单资源b在”另存为”菜单项建立类向导,页面设置如下:选择“Add function”,然后单击“Edit Code”代码如下:void CZhbDoc::OnFileSaveAs(){LPCTSTR lpszFilter="BMP Files(*.bmp)|*.bmp|任何文件|*.*||";CFileDialogdlg(FALSE,lpszFilter,NULL,OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,lpszFilter,NULL);if (dlg.DoModal()!=IDOK)return;CFile file;CFileException fe;if (!file.Open(dlg.GetPathName(), CFile::modeCreate | CFile::modeReadWrite | CFile::shareExclusive, &fe)){// 失败ReportSaveLoadException(dlg.GetPathName(), &fe, TRUE, AFX_IDP_INVALID_FILENAME);return;}file.SeekToBegin();file.Write(&bf,sizeof(bf));file.Write(&bi,sizeof(bi));if(numquad!=0){file.Write(quad,sizeof(RGBQUAD)*numquad);}file.WriteHuge(lpbuf,bi.biSizeImage);file.Close();}。
MFC对话框打开一幅图片并在picture显示和图片保存
学了MFC一段时间后,试着要用对话框打开一幅bmp图像并保存,结果发现网上这些资料太少了,而且有的也讲不清,讲不全,所以自己磕磕碰碰捣鼓了好久,期间也谢谢各位大神的指导,现在我终于完成,特意写出来与大家分享,各位菜鸟共勉。
一、首先要先了解bmp位图结构/d06c23543c1ec5da50e2706d.html可以去看看,内容不多但是够看,也容易懂二、了解位图的显示函数SetStretchBltMode()StretchDIBits()具体函数介绍自己百度一下,我就不多说了三、开始做啦1、新建一个MFC对话框文档默认其他设置,点击完成后会出现这个界面在按钮上单击鼠标右键,在弹出的列表中选择属性把标题改为读取图片再添加一个按钮,把ID改为IDC_SA VE,标题改为保存图片在控件中选择图像,然后在对话框画一个大小适宜的矩形框,在选中对话框点击右键,选择属性,把ID改为IDC_PICTURE回到对话框界面,双击读取图片按钮,这时会弹出一个对话框,点确定然后就会跳到关联函数这边了先把CDialog::OnOK();注释起来,这个是点击按钮后对话框就会关闭的函数然后在// CDialog::OnOK();下面添加以下代码代码都有注释,不懂的地方可以自己再百度//CFileDialog为VC中打开文件对话框类BITMAPFILEHEADER bmpHeader;//文件头BITMAPINFOHEADER bmpInfo;//信息头CFileDialog dlg(TRUE, "*.BMP", NULL, NULL,"位图文件(*.BMP)|*.bmp;*.BMP|",this);CFile bmpFile;//记录打开文件CString strFileName;//记录选择文件路径if (!dlg.DoModal() == IDOK) return;strFileName = dlg.GetPathName();//以只读的方式打开文件if(!bmpFile.Open(strFileName, CFile::modeRead|CFile::typeBinary)) return;if(bmpFile.Read(&bmpHeader,sizeof(BITMAPFILEHEADER)) != sizeof(BITMAPFILEHEADER)){AfxMessageBox("read bmp header failed!");return;}if (bmpHeader.bfType != 0x4d42){AfxMessageBox("invalid file type!");return;}if(bmpFile.Read(&bmpInfo,sizeof(BITMAPINFOHEADER)) != sizeof(BITMAPINFOHEADER)){AfxMessageBox("read bmp infor header failed!");return;}if (bmpInfo.biBitCount != 24){AfxMessageBox("File is not 24 bit.Application doesn't support this kind of file!");return;}pBmpInfo = (BITMAPINFO *)new char[sizeof(BITMAPINFOHEADER)];if (!pBmpInfo){AfxMessageBox("memory error!");return;}//为图像数据申请空间memcpy(pBmpInfo,&bmpInfo,sizeof(BITMAPINFOHEADER));DWORD dataBytes = bmpHeader.bfSize - bmpHeader.bfOffBits;pBmpData = (BYTE*)new char[dataBytes];if (!pBmpData){AfxMessageBox("memory error!");delete pBmpData;return;}if (bmpFile.Read(pBmpData,dataBytes) != dataBytes){AfxMessageBox("Read bmp data failed!");delete pBmpInfo;delete pBmpData;return;}bmpFile.Close();CWnd *pWnd=GetDlgItem(IDC_PICTURE);//获得pictrue控件窗口的句柄CRect rect;pWnd->GetClientRect(&rect);//获得pictrue控件所在的矩形区域CDC *pDC=pWnd->GetDC();//获得pictrue控件的DC//显示图片pDC->SetStretchBltMode(COLORONCOLOR);StretchDIBits(pDC->GetSafeHdc(),0,0,rect.Width(),rect.Height(),0,0,bmpInfo.biWidth,bmpI nfo.biHeight,pBmpData,pBmpInfo,DIB_RGB_COLORS,SRCCOPY);iBmpWidth=bmpInfo.biWidth;iBmpHeight=bmpInfo.biHeight;然后在这个.cpp文件头处添加BITMAPINFO* pBmpInfo; //记录图像细节BYTE* pBmpData; //图像数据int iBmpWidth; // 输入的宽度,以像素为单位int iBmpHeight; // 输入的高度,以像素为单位这些是全局变量,主要是为了后面图像保存可以用的再回到对话框界面,双击保存图片按钮,这时会弹出一个对话框,点确定然后就会跳到关联函数这边了在// TODO: Add your control notification handler code here下添加下面这些代码BITMAPFILEHEADER bmpf;//文件头BITMAPINFOHEADER bmpi;//信息头int Widthbytes;CFile bmpFile;CString strFileName;CFileDialog dlg(FALSE, "*.BMP", NULL, NULL,"位图文件(*.BMP)|*.bmp;*.BMP|");if (!dlg.DoModal() == IDC_SA VE) return;strFileName = dlg.GetPathName();if (bmpFile.Open(strFileName, CFile::modeCreate | CFile::modeReadWrite) == 0) return ;Widthbytes = (iBmpWidth*3+3)/4*4;//位图对齐,确保为4的倍数/* BITMAPFILEHEADER结构填写*/bmpf.bfType = 0x4d42;bmpf.bfOffBits =sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);bmpf.bfSize = bmpf.bfOffBits + Widthbytes *iBmpHeight;bmpf.bfReserved1 = 0;bmpf.bfReserved2 = 0;/* BITMAPINFOHEADER结构填写*/bmpi.biSize = sizeof(BITMAPINFOHEADER);bmpi.biWidth = iBmpWidth;bmpi.biHeight =iBmpHeight;bmpi.biPlanes = 1;bmpi.biBitCount = 24;//24位bmpi.biCompression = BI_RGB;bmpi.biSizeImage =0;bmpi.biXPelsPerMeter = 0;bmpi.biYPelsPerMeter = 0;bmpi.biClrUsed = 0;bmpi.biClrImportant = 0;bmpFile.Write(&bmpf,sizeof(bmpf));//写文件头;bmpFile.Write(&bmpi,sizeof(bmpi));//写信息头;bmpFile.Write(pBmpData,Widthbytes*iBmpHeight);//写图像数据信息;bmpFile.Close();OK全部完成了,编译运行一下,点击打开图片按钮就能显示图片了呵呵,写得不够专业,还望大家不吝赐教。
2.MFC-bmp图片读取保存
第二课 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结构定义如下:typedef struct tagBITMAPINFO {BITMAPINFOHEADER bmiHeader; // 位图信息头RGBQUAD bmiColors[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格式的文件头部分的结构。
MFC-导入显示bmp图片
MFC-导入显示bmp图片lee制作数字图像处理- MFC教程第一课建立MFC和打开bmp图片第一步:建立MFC工程文件--新建--MFC AppWizardd(exe)工程--单文档—确定。
第二步:设置打开函数查看--建立类导向(Ctrl+W)--CpictureXSV iew(类名)--ID_FILE_OPEN(IDs列表)--COMMAND(Messages列表)--默认成员函数名为OnFileOpen --Member Functions(成员函数)中双击该函数进入函数编辑。
建立如下函数:打开图片、保存图片为重点。
注意:在添加Messages列表中:ON_COMMAND是点了按钮或菜单项后的响应消息;ON_UPDA TE_COMMAND_UI是用来表示对应的按钮和菜单项的状态的响应消息,比如你打开这个菜单时,处理这个菜单的状态,比如选中、变灰等。
UPDA TE_COMMAND_UI处理程序的参数是个「指向CCmdUI对象的指针」,而CCmdUI对象就代表着对应的选单命令项,因此你只需呼叫CCmdUI 所准备的,专门用来处理命令项外观的函式(如Enable或SetCheck)即可。
lee制作第三步:View类添加成员函数和成员变量//参数定义public:CString BmpName; //保存图像文件文件名CString EntName; //保存图像文件扩展名CBitmap m_bitmap; //创建位图对象void ShowBitmap(CDC* pDC,CString BmpName); //用来显示指定位图bmp的函数BOOL ShowJpgGif(CDC* pDC,CString strPath, int x, int y);//用来显示指定位图jpg、gif的函数添加方法:选中ClassView区--选中V iew类右键--增加成员变量函数。
lee制作第四步:为ID_FILE_OPEN消息添加打开函数//**************文件打开****************//void CPictureMapView::OnFileOpen(){//四种格式的文件:bmp gif jpg tiffCString filter;filter="所有文件(*.bmp,*.jpg,*.gif,*tiff)|*.bmp;*.jpg;*.gif;*.tiff| BMP(*.bmp)|*.bmp| JPG(*.jpg)|*.jpg| GIF(*.gif)|*.gif| TIFF(*.tiff)|*.tiff||";CFileDialog dlg(TRUE,NULL,NULL,OFN_HIDEREADONLY,filter,NULL);//按下确定按钮dlg.DoModal() 函数显示对话框if( dlg.DoModal() == IDOK ){//获取路径文件名扩展文件名BmpName = dlg.GetPathName();//BmpName.Format(_T("%s",str));//重点:错误会出现错误的路径//AfxMessageBox(BmpName);//显示图片的路径:打桩功能EntName = dlg.GetFileExt();EntName.MakeLower(); //此成员函数将此CString对象转换为一个小写字符串/**********************************************//** 使用CString处理字符串可处理Unicode、ANSI **//** CString中的Format进行字符串转换**//**********************************************/Invalidate();//调用该函数就会调用ONDRA W画图}}lee制作第五步:新建菜单和最近使用菜单不可用MFC ClassWizard(ctrl+W)--CpictureXSV iew(类名)--ID_FILE_NEW(IDs列表)—UPDA TE_COMMAND_UI(Messages列表)—选择默认成员函数名--Member Functions(成员函数)中双击该函数进入函数编辑。
BMP文件结构读写操作(图文)
BMP文件结构读写操作(图文)预览说明:预览图片所展示的格式为文档的源格式展示,下载源文件没有水印,内容可编辑和复制BITMAPFILEHEADER结构的各个域详细说明如下:bfType:位图文件类型,必须是0x424D,即字符串“BM”,也就是说,所有的“*.bmp”文件的头两个字节都是“BM”。
的大小为,图像中有分量相等,整个颜色表的大小为第二,一般来说,BMP文件的数据是从图像的左下角开始逐行扫描图像的,即从下到上、从左到右,将图像的像素值一一记录下来,因此图像坐标零点在图像左下角。
2.BMP文件的存盘给定图像路径名以及图像的数据,对图像的写操作也是按照BMP 文件4个组成部分进行分别处理的。
其基本流程如图1-9所示。
int biBitCount, RGBQUAD *pColorTable){//如果位图数据指针为0,则没有数据传入,函数返回if(!imgBuf)return 0;//颜色表大小,以字节为单位,灰度图像颜色表为1024字节,彩色图像颜色表大小为0int colorTablesize=0;if(biBitCount==8)colorTablesize=1024;//待存储图像数据每行字节数为4的倍数int lineByte=(width * biBitCount/8+3)/4*4;//以二进制写的方式打开文件FILE *fp=fopen(bmpName,"wb");if(fp==0) return 0;//申请位图文件头结构变量,填写文件头信息BITMAPFILEHEADER fileHead;fileHead.bfType = 0x4D42;//bmp类型//bfSize是图像文件4个组成部分之和fileHead.bfSize= sizeof(BITMAPFILEHEADER)+ sizeof(BITMAPINFOHEADER)+ colorTablesize + lineByte*height;fileHead.bfReserved1 = 0;fileHead.bfReserved2 = 0;//bfOffBits是图像文件前3个部分所需空间之和fileHead.bfOffBits=54+colorTablesize;//写文件头进文件fwrite(&fileHead, sizeof(BITMAPFILEHEADER),1, fp); //申请位图信息头结构变量,填写信息头信息BITMAPINFOHEADER head;head.biBitCount=biBitCount;head.biClrImportant=0;head.biClrUsed=0;head.biCompression=0;head.biHeight=height;head.biPlanes=1;head.biSize=40;head.biSizeImage=lineByte*height;head.biWidth=width;head.biXPelsPerMeter=0;head.biYPelsPerMeter=0;//写位图信息头进内存fwrite(&head, sizeof(BITMAPINFOHEADER),1, fp);//如果灰度图像,有颜色表,写入文件该main()函数将指定BMP文件读入内存,将图像信息打印输出,最后又原样存入指定文件中。
MFC保存图片或图形
这几个函数可以完全搞定,颜色你自己可以修改下BOOL C**Dlg::SaveFILe(HBITMAP hBitmap, CString FileName){ int iBits;WORD wBitCount;DWORD dwPaletteSize=0, dwBmBitsSize=0, dwDIBSize=0, dwWritten=0;BITMAP Bitmap;BITMAPFILEHEADER bmfHdr;BITMAPINFOHEADER bi;LPBITMAPINFOHEADER lpbi;HANDLE fh, hDib, hPal,hOldPal=NULL;hDC = CreateDC("DISPLAY", NULL, NULL, NULL);iBits = GetDeviceCaps(hDC, BITSPIXEL) * GetDeviceCaps(hDC, PLANES);DeleteDC(hDC);if (iBits <= 1) wBitCount = 1;else if (iBits <= 4) wBitCount = 4;else if (iBits <= 8) wBitCount = 8;else wBitCount = 24;GetObject( hBitmap, sizeof( Bitmap ), ( LPSTR )&Bitmap );bi.biSize = sizeof( BITMAPINFOHEADER );bi.biWidth = Bitmap.bmWidth;bi.biHeight = Bitmap.bmHeight;bi.biPlanes = 1;bi.biBitCount = wBitCount;bi.biCompression = BI_RGB;bi.biSizeImage = 0;bi.biXPelsPerMeter = 0;bi.biYPelsPerMeter = 0;bi.biClrImportant = 0;bi.biClrUsed = 0;dwBmBitsSize = ((Bitmap.bmWidth * wBitCount + 31) / 32) * 4 * Bitmap.bmHeight;hDib = GlobalAlloc(GHND,dwBmBitsSize + dwPaletteSize + sizeof(BITMAPINFOHEADER)); lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDib);*lpbi = bi;hPal = GetStockObject(DEFAULT_PALETTE);if (hPal){hDC = ::GetDC(NULL);//hDC = m_pDc->GetSafeHdc();hOldPal = ::SelectPalette(hDC, (HPALETTE)hPal, FALSE);RealizePalette(hDC);}GetDIBits(hDC, hBitmap, 0, (UINT) Bitmap.bmHeight, (LPSTR)lpbi + sizeof(BITMAPINFOHEADER)+dwPaletteSize, (BITMAPINFO *)lpbi, DIB_RGB_COLORS);if (hOldPal){::SelectPalette(hDC, (HPALETTE)hOldPal, TRUE);RealizePalette(hDC);::ReleaseDC(NULL, hDC);}fh = CreateFile(FileName, GENERIC_WRITE,0, NULL, CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);if (fh == INVALID_HANDLE_VALUE) return FALSE;bmfHdr.bfType = 0x4D42; // "BM"dwDIBSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + dwPaletteSize + dwBmBitsSize; bmfHdr.bfSize = dwDIBSize;bmfHdr.bfReserved1 = 0;bmfHdr.bfReserved2 = 0;bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEADER) + dwPaletteSize; WriteFile(fh, (LPSTR)&bmfHdr, sizeof(BITMAPFILEHEADER), &dwWritten, NULL);WriteFile(fh, (LPSTR)lpbi, dwDIBSize, &dwWritten, NULL);GlobalUnlock(hDib);GlobalFree(hDib);CloseHandle(fh);return TRUE;}HBITMAP C**Dlg::CopyDCToBitmap(HDC hScrDC, LPRECT lpRect){HDC hMemDC;HBITMAP hBitmap,hOldBitmap;int nX, nY, nX2, nY2;// 选定区域坐标int nWidth, nHeight;if ( IsRectEmpty( lpRect ) ) return NULL;nX= lpRect->left;nY= lpRect->top;nX2 = lpRect->right;nY2 = lpRect->bottom;nWidth = nX2 - nX;nHeight = nY2 - nY;//为屏幕设备描述表创建兼容的内存设备描述表hMemDC= CreateCompatibleDC( hScrDC );// 创建一个与屏幕设备描述表兼容的位图hBitmap = CreateCompatibleBitmap( hScrDC, nWidth, nHeight );// 把新位图选到内存设备描述表中hOldBitmap = ( HBITMAP )SelectObject( hMemDC, hBitmap );// 把屏幕设备描述表拷贝到内存设备描述表中StretchBlt( hMemDC, 0, 0, nWidth, nHeight, hScrDC, nX, nY, nWidth, nHeight, SRCCOPY ); //得到屏幕位图的句柄hBitmap = ( HBITMAP )SelectObject( hMemDC, hOldBitmap );//清除DeleteDC( hMemDC );DeleteObject( hOldBitmap );//返回位图句柄return hBitmap;}void C**Dlg::OnbuildBitmap( ){CDC *pdc=GetDC();//----------------------------------------------------// 下面是创建兼容DC和兼容DC使用的CBitmap,并规定兼容// DC的绘图绘制在创建的CBitmap上。
bmp文件读写操作
实验一BMP文件的读写操作一、实验目的与要求1.熟悉及掌握在MATLAB中能够处理哪些位图文件。
2.熟练掌握在MATLAB中如何读取位图文件。
3.掌握如何利用MATLAB来获取位图文件的大小、颜色、高度、宽度等等相关信息。
4.掌握如何在MATLAB中按照指定要求存储一幅位图文件的方法。
5.图像间如何转化。
二、实验原理及知识点1.位图文件的分类及结构位图是通过许多像素点表示一幅图像,每个像素具有颜色属性和位置属性。
位图可以分成如下四种:线画稿 、灰度图像、索引颜色图像和真彩色图像。
位图文件(Bitmap-File,BMP)格式是Windows采用的图像文件存储格式,在Windows环境下运行的所有图像处理软件都支持这种格式。
Windows 3.0以前的BMP位图文件格式与显示设备有关,因此把它称为设备相关位图(device-dependent bitmap,DDB)文件格式。
Windows 3.0以后的BMP位图文件格式与显示设备无关,因此把这种BMP位图文件格式称为设备无关位图(device-independent bitmap,DIB)格式,目的是为了让Windows能够在任何类型的显示设备上显示BMP 位图文件。
BMP 位图文件默认的文件扩展名是BMP 或者bmp 。
由四部分组成,其结构如图1所示。
图1 BMP 文件结构图2. MATLABMATLAB 是由美国MathWorks 公司推出的用于数值计算的有力工具, 它具有相当强大的矩阵运算和操作功能,一幅数字图像在MATLAB 中可以很自然的表示成矩阵,如图2,一幅M ×N 个像素的数字图像,其像素灰度值可以用M 行、N 列的矩阵G 表示:图2数字图像的矩阵的表示并且MATLAB 图像处理工具箱(IPT )提供了丰富的图像处理函数,这些函数处理的是多维数组,而图像(二维数值数组)正是多维数组的一种特例。
灵活运用这些函数几乎可以完成所有的图像处理工作,⎥⎥⎥⎥⎥⎥⎦⎤⎢⎢⎢⎢⎢⎢⎣⎡=MN M M N N g g g g g g g g g G 212222111211从而大大节省编写低层算法代码的时间,避免程序设计中的重复劳动,达到事半功倍的效果。
1怎样读取BMP文件中的像素数据与显示位图
1怎样读取BMP文件中的像素数据与显示位图怎样读取BMP位图的数据与显示位图计算机与信息工程系管庶安一 BMP位图文件的结构以24位BMP位图文件为例说明。
BMP位图文件结构如下表所示:二读取BMP位图数据(1)在MFC工程中的 .H文件中定义如下全局成员变量:BITMAPFILEHEADER FileHead;// 定义存放.BMP 文件头的结构BITMAPINFOHEADER BmpInfo;// 定义存放.BMP 信息头的结构LPBYTE lpImage;// 定义存放.BMP文件中的位图数据的BYTE 型指针typedef struct CCC{ // 定义能存放一个像素的3个基色值的结构类型BYTE B;BYTE G;BYTE R;};CCC C3 [480] [640];// 定义能存放一幅480行、640列像素的二维数组,以便图像处理与识别时运算(2)在.CPP文件中的类构造函数中,为lpImage指针申请内存:lpImage=(LPBYTE)new BYTE[640*480*3];在.CPP文件中的类析构函数中,为lpImage指针释放内存:delete[ ] lpImage;(3)在.CPP文件中的适当函数中打开.BMP文件,读取信息头和位图数据。
CFile f;BOOL OK;OK=f.Open( Bmp.PathName,CFile::modeRead|CFile::typeBinary|CFile::shareExclusive,NULL);if(!OK) return(-1); //不能打开文件,返回失败标志-1f.Read(&FileHead,sizeof(FileHead)); //读文件头if(FileHead.bfType!=0x4d42) {f.Close();return -2; //不是BMP文件,返回失败标志-2}short x,y,z;z=(BmpInfo.biWidth*3/4)*4+(BmpInfo.biWidth*3%4==0 ? 0 :4);f.Read(&BmpInfo,sizeof(BmpInfo)); //读信息头f.Seek(FileHead.bfOffBits,0);f.Read(lpImage,BmpInfo.biHeight*z); //读全部位图数据f.Close();for(y=BmpInfo.biHeight-1;y>=0;y--){memcpy(C3[y],lpImage+(BmpInfo.biHeight-1-y)*z,z); //逐行将位图数据填写到C3数组中}return 1; //最后,返回成功标志1三显示位图1 先按上述方法读取位图数据,再将读取数据予以显示。
BMP图像格式详解及VB函数截图保存
BMP图像格式详解及VB截图保存方法2012-03-06 13:14BMP是一种与硬件设备无关的图像文件格式,使用非常广。
它采用位映射存储格式,除了图像深度可选以外,不采用其他任何压缩,因此,BMP文件所占用的空间很大。
BMP文件的图像深度可选lbit、4bit、8bit及24bit。
BMP文件存储数据时,图像的扫描方式是按从左到右、从下到上的顺序。
由于BMP文件格式是Windows环境中交换与图有关的数据的一种标准,因此在Windows环境中运行的图形图像软件都支持BMP图像格式。
文件结构:典型的BMP图像文件由四部分组成:1:位图文件头数据结构,它包含BMP图像文件的类型、显示内容等信息;2:位图信息数据结构,它包含有BMP图像的宽、高、压缩方法,以及定义颜色等信息;3:调色板,这个部分是可选的,有些位图需要调色板,有些位图,比如真彩色图(24位的BMP)就不需要调色板;4:位图数据,这部分的内容根据BMP位图使用的位数不同而不同,在24位图中直接使用RGB,而其他的小于24位的使用调色板中颜色索引值。
位图的类型:位图一共有两种类型,即:设备相关位图(DDB)和设备无关位图(DIB)。
DDB位图在早期的Windows系统(Windows 3.0以前)中是很普遍的,事实上它也是唯一的。
然而,随着显示器制造技术的进步,以及显示设备的多样化,DDB位图的一些固有的问题开始浮现出来了。
比如,它不能够存储(或者说获取)创建这张图片的原始设备的分辨率,这样,应用程序就不能快速的判断客户机的显示设备是否适合显示这张图片。
为了解决这一难题,微软创建了DIB位图格式。
设备无关位图 (Device-Independent Bitmap)DIB位图包含下列的颜色和尺寸信息:*原始设备(即创建图片的设备)的颜色格式。
*原始设备的分辨率。
*原始设备的调色板*一个位数组,由红、绿、蓝(RGB)三个值代表一个像素。
*一个数组压缩标志,用于表明数据的压缩方案(如果需要的话)。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
第二课 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结构定义如下:typedef struct tagBITMAPINFO {BITMAPINFOHEADER bmiHeader; // 位图信息头RGBQUAD bmiColors[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结构时我定义成系统自带的结构:BITMAPFILEHEADER bfh;BITMAPINFOHEADER bih;而不是BITMAPFILEHEADER_ ,因为MFC中用自带的定义图片头文件信息是正确的,但在位图信息块总会在文件最后多出2字节并默认为CD(0x16进制)。
原因可能是自定义的图片头文件少2字节,在后面补充了2字节。
(未知)/*******************************************************//* BMP位图文件包括4部分: *//* 位图文件头结构BITMAPFILEHEADER *//* 位图信息头结构BITMAPINFOHEADER *//* 位图颜色表RGBQUAD *//* 位图像素数据*//*******************************************************/#ifndef _IMAGESTRUCT_#define _IMAGESTRUCT_/*14byte BMP文件头含有BMP文件的类型、大小、位图文件的保留字、位图数据距文件头的偏移量*/typedef struct T_BITMAPFILEHEADER {WORD bfType; //2byte 位图文件的类型,必须为BM 0x424dDWORD bfSize; //4byte 位图文件的大小,以字节为单位WORD bfReserved1; //2byte 位图文件保留字,必须为0WORD bfReserved2; //2byte 位图文件保留字,必须为0DWORD bfOffBits; //4byte 位图数据距文件头的偏移量(字节)} BITMAPFILEHEADER_;/*40byte BMP位图信息头用于说明位图的尺寸等信息*/typedef struct T_BITMAPINFOHEADER {DWORD biSize; //本结构所占用字节数LONG biWidth; //位图的宽度,以像素为单位LONG biHeight; //位图的高度,以像素为单位WORD biPlanes; //目标设备的级别,必须为1WORD biBitCount;//每个像素所需的位数,必须是1(双色)、4(16色)、8(256色)或24(真彩色)之一DWORD biCompression;//位图压缩类型,必须是0(不压缩)1(BI_RLE8压缩类型)或2(BI_RLE压缩类型)之一DWORD biSizeImage; //位图的大小,以字节为单位LONG biXPelsPerMeter; //位图水平分辨率,每米像素数LONG biYPelsPerMeter; //位图垂直分辨率,每米像素数DWORD biClrUsed; //位图实际使用的颜色表中的颜色数DWORD biClrImportant; //位图显示过程中重要的颜色数} BITMAPINFOHEADER_;/*BMP位图颜色表*/typedef struct T_RGBQUAD{BYTE rgbBlue; //蓝色的亮度(值范围为0~255)BYTE rgbGreen; //绿色的亮度(值范围为0~255)BYTE rgbRed; //红色的亮度(值范围为0~255)BYTE rgbReserved; //保留,必须为0} RGBQUAD_;#endif第二步:在..View.h中添加共有成员变量和成员函数1.找到..View.h头文件添加:#include "ImageStruct.h"2.在Class CBmpDrawView : public Cview中的public中添加成员变量函数:public://用来保存bmp格式图片bool SaveBmp(LPCSTR lpFileName);//用来读取bmp图片bool ReadBmp();//用来显示指定位图jpg、gif的函数bool ShowJpgGif(CDC* pDC,CString strPath, int x, int y);//用来显示指定位图bmp的函数void ShowBitmap(CDC* pDC,CString BmpName);/*CBitmap m_bitmaplin; 创建临时位图对象进行处理*/CBitmap m_bitmap; //创建位图对象CString EntName; //保存图像文件扩展名CString BmpName; //保存图像文件文件名int m_nWidth; //图像实际宽度int m_nHeight; //图像实际高度int m_nDrawWidth; //图像显示宽度int m_nDrawHeight; //图像显示高度DWORD m_nImage; //图像数据的字节数只含位图DWORD相当于long intDWORD m_nSize; //图像文件大小int m_nLineByte; //图像一行所占字节数int m_nBitCount; //图像每个像素所占位数int m_nPalette; //位图实际使用的颜色表中的颜色数/*注意:信息头必须条用系统bmp的结构BITMAPFILEHEADER 否则会多2字节*/ BITMAPFILEHEADER bfh; //全局变量文件头BITMAPINFOHEADER bih; //全局变量信息头RGBQUAD *m_pPal; //颜色表指针BYTE *m_pImage; //读入图片数据后的指针BYTE相当于unsigned char virtual ~CBmpDrawView();第三步:添加readbmp函数添加函数的方法:a.在View.h的public中直接添加函数bool ReadBmp()像第二步中一样;然后在View.cpp中添加函数:bool CBmpDrawView::ReadBmp(){}。
b.选中ClassView区--选中View类右键--增加成员变量函数—函数类型为bool—函数名为ReadBmp()—函数Access为public。
程序会自动在View.cpp中添加函数:bool CBmpDrawView::ReadBmp(){}。
c.添加代码://************************写入bmp格式图片过程***************************//bool CBmpDrawView::ReadBmp(){FILE *fp = fopen(BmpName,"rb"); //读取bmp图片BmpName为图片的绝对路径if(fp==0) { AfxMessageBox("无法打开文件!",MB_OK,0); return 0; }/*读取文件头全局变量bfh BITMAPFILEHEADER 定义在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); return 0; }/*读取信息头*//*解决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("本结构所占用字节数出现错误"); return 0; }/*位图压缩类型:必须是0(不压缩)、1(BI_RLE8压缩类型)、2(BI_RLE压缩类型)之一*/ if(bih.biCompression == BI_RLE8 || bih.biCompression == BI_RLE4){ AfxMessageBox("位图被压缩!"); return 0; }/*获取图像高宽和每个像素所占位数*/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);return true;}第四步:添加保存menu控件和函数a.查看--建立类导向(Ctrl+W)--CpictureXSView(类名)--ID_FILE_SAVE(IDs 列表)--COMMAND(Messages列表)--默认成员函数名为OnFileSave --Member Functions(成员函数)中双击该函数进入函数编辑。