在VC++中如何将绘制的图形存储成位图
- 格式:pdf
- 大小:131.71 KB
- 文档页数:21
怎么样在VC中使用Static控件来显示图像?在使用MFC编写程序时,经常需要显示图像;根据GDI的要求,需要一个DC(设备内容)作为显示的基础;实际上任何Windows的窗口都可以作为一个DC,我们可以通过API或MFC的函数来得到,例如:HDC GetDC (HWND);---这里的HWND是窗口的句柄CDC * CWnd::GetDC ();---这里的CWnd实际上是任何从CWnd的类当我们使用MFC的单文档或多文档框架时,我们可以使用CView作为图像显示的DC,这个时候我们将绘制图像的操作放在OnDraw中就可以了;当窗口无效或更新的时候,框架会自动调用该函数来重新绘制图像;这里没有什么问题,我们主要来谈谈另外一种模式:当你需要在一个基于Dialog程序或一个CDialog控件中显示图像的问题。
实际上什么控件都可以作为图像显示的DC,他们可以是按钮、图片控件、Static控件等,只要有窗口的控件都可以得到DC。
这里仅以Static控件作为图像显示的控件来介绍。
首先看我程序的基本逻辑:源文件后面的按钮是用来选择位图文件的;而下面的图像显示区域是用来显示图像的Static 控件;当设置好要显示的图像文件以后,图像就自动在Static中画出来。
●第一次一开始,我在CDialog对应的按钮处理程序中调用显示图像的代码,代码如下(IDC_PICVIEW为Static的ID):然后在CImageCntDlg::OnPaint中也调用ShowImage(TRUE);然后编译运行。
一开始还可以,选择BMP文件之后也可以正确选择,但当激活另一个程序(也就是隐藏了该窗口),然后再激活这个程序,这个时候发现Static中图像显示闪烁一下后变成灰色的背景。
到底什么发生了?●到底什么发生了?上面的现象告诉我们,即使我们将ShowImage放在CDialog的WM_PAINT处理消息中,在某些情况下仍然不能正确的处理。
pb的bitmap用法
PB(PowerBuilder)中的bitmap可以通过以下步骤进行使用:
1. 创建一个位图(bitmap)对象。
2. 定义位图的数据类型,可以是8位无符号整数(uint8)或16位无符号整数(uint16)。
3. 初始化位图,可以使用位图编辑器或编程方式进行初始化。
4. 在应用程序中,可以使用位图对象进行图像处理、显示等操作。
例如,可以将位图显示在窗口、控件或打印机上,也可以将位图保存到文件中。
5. 如果需要将位图数据保存到数据库中,可以使用PowerBuilder 的数据窗口(DataWindow)控件,将位图数据作为二进制数据类型存储在数据库中。
以上是PB中bitmap的基本用法,具体实现方式可能因PowerBuilder版本和开发环境而有所不同。
建议参考PowerBuilder的官方文档或相关教程进行深入学习。
Visual C++/MFC入门教程闻怡洋第一章VC入门1.1 如何学好VC1.2 理解Windows消息机制1.3 利用Visual C++/MFC开发Windows程序的优势1.4 利用MFC进行开发的通用方法介绍1.5 MFC中常用类、宏、函数介绍第二章图形输出2.1 和GUI有关的各种对象2.2 在窗口中输出文字2.3 使用点、刷子、笔进行绘图2.4 在窗口中绘制设备相关位图、图标、设备无关位图2.5 使用各种映射方式2.6 多边形和剪贴区域第三章文档视结构3.1 文档视图框架窗口间的关系和消息传送规律3.2 接收用户输入3.3 使用菜单3.4 文档、视、框架之间相互作用3.5 利用序列化进行文件读写3.6 MFC中所提供的各种视类介绍第四章窗口控件 (28)4.1 Button4.2 Static Box4.3 Edit Box4.4 Scroll Bar4.5 List Box/Check List Box4.6 Combo Box/Combo Box Ex4.7 Tree Ctrl4.8 List Ctrl4.9 Tab Ctrl4.A Tool Bar4.B Status Bar4.C Dialog Bar4.D 利用AppWizard创建并使用ToolBar StatusBar Dialog Bar4.E General Window4.F 关于WM_NOTIFY的使用方法第五章对话框 (50)5.1 使用资源编辑器编辑对话框5.2 创建有模式对话框5.3 创建无模式对话框5.4 在对话框中进行消息映射5.5 在对话框中进行数据交换和数据检查5.6 使用属性对话框5.7 使用通用对话框5.8 建立以对话框为基础的应用5.9 使用对话框作为子窗口第六章网络通信开发6.1 WinSock介绍6.2 利用WinSock进行无连接的通信6.3 利用WinSock建立有连接的通信※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※第一章VC入门1.1 如何学好VC这个问题很多朋友都问过我,当然流汗是必须的,但同时如果按照某种思路进行有计划的学习就会起到更好的效果。
摘要:本文简单介绍了位图文件的两种存储格式,并且在VC++6.0下实现了读取位图文件中的数据,用SetPixel()函数在窗口中重现图像,最后在程序中实现了一种存储格式到另一种存储格式的转换。
关键字:BMP、灰度位图、24位真彩色位图、存储格式一、前言BMP(Bitmap的缩写)图像是指文件名后缀为BMP的位图图像。
位图图像在计算机中使用很广泛,例如在windows中,记事本、写字板中的文字就是用位图图像表示出来的。
许多以其它格式存储的图像,就是在位图图像的基础上,进行优化处理后得到的,例如JPEG图像等。
在数字图像处理中,许多算法就是针对24位真彩色位图或灰度位图设计的。
因此,很有必要介绍一下位图文件的这两种存储格式。
二、24位真彩色图像存储格式把下图的24位真彩色图像格式在16位编辑器(例如VC编辑器)中打开,可以看到图像的二进制数据。
24位真彩色的二进制数据为:这是24位真彩色位图文件数据一部分。
这一部分数据包括位图文件头、位图信息头和位图阵列三部分。
(一)位图文件头位图文件头用来记录标志文件大小的一些信息,在文件中占14个字节,存储的内容如下:字节 1 2 3 4 5 6 7 8 9 10 11 12 13 14 000000 42 4D CC B4 02 00 00 00 00 00 36 00 00 00 其中:42 4D 为位图的标志,即ASCII码为BMCC B4 02 表示位图文件的总字节数,换算成十进制为(02B4CC)H=(177356)10,即这副图像的大小为177356字节。
00 00 00 00 00 为保留字节,用来存储文件大小的数据。
36 00 00 00 00 表示位图阵列的起始位置,(36)H=(54)10即54字节开始为位图阵列。
(二) 位图信息头位图信息头记录和位图相关的一些信息,在文件中占40个字节,存储的内容如下:字节 1 2 3 4 5 6 7 8 9 10 11121314151600000 0 2800001 6 02C1C511800003 2 012B12B00004 8 0其中:28 00 00 00 表示信息头的长度,(28)H=(40)10,即位图信息头占40个字节。
在 Mastercam 2017 中保存图纸(drawing)的步骤如下:
1. 打开你想要保存的图纸文件。
2. 在 Mastercam 顶部的菜单栏中选择 "File(文件)"。
3. 在下拉菜单中选择 "Save As(另存为)" 选项。
4. 弹出一个对话框,其中包含保存文件的选项。
5. 在对话框中,选择一个合适的文件位置和文件名,用于保
存图纸文件。你可以通过浏览文件夹来选择保存的位置,也
可以在文件名文本框中输入你想要保存的文件名。
6. 选择保存文件的格式。在 Mastercam 中,图纸文件的常
见格式包括 Mastercam Drawing File(MCD),DXF 文件等。
选择适当的文件格式以满足你的需求。
7. 点击 "Save(保存)" 按钮,将图纸文件保存到指定的位
置。
请注意,以上步骤仅适用于 Mastercam 2017 版本,不同版
本的 Mastercam 可能会有些许差异。另外,请确保你具有
足够的文件操作权限来保存文件到指定的位置。
VC++显⽰图像的⼏种⽅法及获取DC的⽅法⼀、获取DC⽅法为了进⾏绘图,必须获得⼀个设备描述表DC。
有多种⽅式获得DC:1、利⽤windows SDK全局函数获得HDC hdc;Hdc=::GetDC(m_hWnd);…::ReleaseDC(m_hWnd,hdc);2、利⽤MFC的CDC封装类实现CDC *pDC=GetDC();…ReleaseDC(pDC);3、利⽤MFC的CClientDC类实现,此类派⽣于CDC类,并在构造函数中调⽤GetDC,在析构函数中调⽤ReleaseDC。
CClientDC dc(this);This指针代表CClientDC对象所属的类对象,如视图类CXXView⼆、有多种⽅法实现在窗⼝中显⽰位图:1、BitBlt函数和StretchBlt函数(属于CDC类)(1)创建位图CBitmap bitmap; bitmap.LoadBitmap(IDB_BITMAP); //加载应⽤程序中的资源位图(2)创建兼容DCCDC dcCompatible; dcCompatible.CreateCompatibleDC(pDC);(3)将位图选⼊兼容DC中dcCompatible.SelectObject(&bitmap);(4)将兼容DC中的位图贴到当前DC中pDC->BitBlt(rect.left,rect.top,rect.width,rect.height,&dcCompatible,0,0,SRCCOPY);BOOL BitBlt(int x,int y,int nWidth,int nHeight,CDC *pSrcDC,int xSrc,int ySrc,DWORD dwRop);x和y指定⽬标矩形左上⾓的坐标。
nWidth,nHeight指定⽬标矩形区域宽度和⾼度。
xSrc和ySrc指定源矩形区域左上⾓的x和y坐标。
得到rect GetClientRect(&rect);BOOL StretchBlt(int x,int y,int nWidth,int nHeight,CDC *pSrcDC,int xSrc,int ySrc,int nSrcWidth,intnSrcHeight,DWORD dwRop);StretchBlt函数⽐BitBlt函数多了两个参数nSrcWidth和nSrcHeight,表⽰原矩形的宽度和⾼度。
VC编程实现灰度图像与彩色图像的相互转换PhotoShop的图像处理功能很强,其中有一个功能是将灰度图像转换为彩色图像,数字图像处理中,也经常要遇到灰度图像与彩色图像相互转换的问题,如何自己解决这个问题,值得大家探讨,现将我解决这类问题的方法陈述如下:工程应用中经常要遇到需要把彩色图像到灰度图像的变换的问题,采集卡过来的图像为彩色图像,为加快处理速度,要把彩色图像转换为黑白图象,这个问题比较好解决,一般情况下彩色图像每个像素用三个字节表示,每个字节对应着R、G、B分量的亮度(红、绿、蓝),转换后的黑白图像的一个像素用一个字节表示该点的灰度值,它的值在0~255之间,数值越大,该点越白,既越亮,越小则越黑。
转换公式为Gray(i,j)=0.11*R(i,j)+0.59*G(i,j)+0.3*B(i,j),其中Gray(i,j)为转换后的黑白图像在(i,j)点处的灰度值,我们可以观察该式,其中绿色所占的比重最大,所以转换时可以直接使用G值作为转换后的灰度。
至于灰度图像转换为彩色图像,技术上称为灰度图像的伪彩色处理,这是一种视觉效果明显而技术又不是很复杂的图像增强技术。
灰度图像中,如果相邻像素点的灰度相差不大,但包含了丰富的信息的话,人眼则无法从图像中提取相应的信息,因为人眼分辨灰度的能力很差,一般只有几十个数量级,但是人眼对彩色信号的分辨率却很强,这样将黑白图像转换为彩色图像人眼可以提取更多的信息量。
在转换过程中,经常采用的技术是灰度级-彩色变换,意思就是对黑白图像上的每一个像素点,取得该点的灰度值并送入三个通道经过实施不同的变换,产生相应的R、G、B的亮度值,即所求彩色图像对应像素点的彩色值,具体变换公式很多,我采用的是最常用的一种,变换曲线图如下:上图中,三个图分别代表了三个变换通道,R、G、B指的是变换后对应点的R、G、B分量值,L指的是各个分量的最大值为255,G(x,y)为相应点的灰度值。
BMP位图文件存储初探赵柳青(重庆市綦江南州中学校,重庆401420)摘要:关于位图文件存储大小的计算,普遍采用估算法,估算带来的一个问题是随着位图的增大,误差也就越来越大,以至于超出了预期准备的存储空间。
从提出问题、分析问题、解决问题等方式推导出精确计算位图文件大小的公式,以帮助读者来解决在实际应用位图存储时应该注意的问题。
关键词:位图;编码;存储空间;Windows7系统在计算机领域,图片是指静止的画面,它包含图形和图像两种。
其中,图像是利用数码相机、扫描仪等设备获取的实际景物的一个映象,最小的元素是像素。
相对图形,图像的色彩更加丰富,画面也更加复杂,与实际景物接近,真实感强,故而图像的文件容量更大。
由于图像是由像素构成,因此图像放大之后,会出现失真的情况[1」。
位图图像(Bitmap)简写为BMP,文件名后缀为. bmp,它是按照顺序存储每个像素点颜色的方式来获得的图片文件。
位图图像在计算机中的使用非常广泛叫1提出问题重庆市高中信息技术学科使用新教材为广东教育出版社出版的信息技术必修1《数据与计算》第一章第二节“图像编码”(第12页)中,提到:一般情况下,位图文件所占的空间可按以下公式计算:文件的大小=文件头+信息头+颜色表项+图像分辨率x图像量化位数衣8揖3铱...........①在公式①中,计算了文件头、信息头、颜色表项等附加于位图文件一些信息,由此可以看出作者是想通过这样的计算来精确得出位图文件存储时的大小,即位图文件所占的最小存储空间大小,但事实是,这样计算的结果与Windows系统中位图文件属性所示的大小有差距,而且有时会随着位图尺寸的增加差值会越来越大。
为了科学地了解位图文件的存储,特地先做了一番验证。
2验证问题为了严谨地进行验证,从像素大小、颜色、量化位数等几个方面,用mspaint软件绘制了大量的BMP位图文件,将这些文件属性里的大小和实际计算大小进行比较、分析,形成了下列的表格。
作者简介:高伟卫,女,1963年生,太原理工大学在读硕士研究生。
引言图形图像信息的利用和沟通,已应用到各行各业(如自动控制系统、消防和火灾报警系统、城市环境等)。
本文将对BMP位图文件的格式的结构组成进行分析,基于此结构阐述一种如何用VC++6.0的基础类库MFC实现图形图像显示的方法。
1图形图像格式计算机中图形图像文件大致可分为位图和矢量图文件。
前者以点阵形式显示图像,一般作为照片、特效字之类颜色复杂的图像所采用的格式;后者是以数学方法描述的一种由几何元素组成的图形,对图形的表达细致、真实、缩放后分辨率不变,在卡通画、工程样图等图形处理中应用较多。
这两类图形图像,信息存贮方式不同,目前,描述格式很多。
位图格式如BMP(WindowsBitmap)、GIF(GraphicsInterchangeFormat)、JPEG或JPG(JointPhotographicExpertsGroup)等;矢量图格式如DXF(DocumentExchangeFormat)、EPS(EncapsulatedPostScript)、WMF(Windows源文件)等。
BMP是Windows操作系统中的标准图像文件格式,有两种类型:设备相关位图(DDB)和设备无关位图(DIB)。
它能够被多种Windows应用程序所支持,是处理图像较方便、较通用的方法。
BMP格式文件结构由四部分组成:(1)文件头(BITMAPFILEHEADER):其数据结构含有BMP文件的类型、文件大小、位图起始位置等信息。
其定义为:typedefstructtagBITMAPFILEHEADER{WORDbfType;//位图文件有类型,必须为BMDWORDbfSize;//位图文件的大小,以字节为单位,14字节WORDbfReservedl;//位图文件保留字,必须为0WORDbfReserved2;//位图文件保留字,必须为0DWORDbfOffBits;//位图数据的起始位置,到文件头偏移字节数}BITMAPFILEHEADER;(2)信息头(BITMAPINFOHEADER):其数据用于说明位图的尺寸等信息,其定义为:typedefstructtagBITMAPINFOHEADER{DWORDbiSize;//本结构所占用字节数,40字节LONGbiWidth;//位图的宽度,以像素为单位LONGbiHeight;//位图的高度,以像素为单位WORDbiPlanes;//目标设备的级别,必须为1WORDbiBitCout//每个像素所需的位数,必须是1(双色),4(16色),8(256色)或24(真彩色)之一DWORDbiCompression;//位图压缩类型,必须是0(不压缩),1(BI_RLE8压缩类型)或2(BI_RLE4压缩类型)之一DWORDbiSizelmage;//位图的大小,以字节为单位LONGbiXPelsPerMeter;//位图水平分辨率,每米像素数LONGbiXPelsPerMeter;//位图垂直分辩率,每米像素数DWORDbiClrUsed;//位图实际使用的颜色表中的颜色数DWORDbiClrImportant;//位图显示过程中重要的颜色数}BITMAPINFOHEADER;(3)调色板(PALETTE):是对那些需要调色板的位图文件而言,有些位图(如真彩色图)不需要调色板,BITMAPINFOHEADER后直接是图形数据。
在VC++6.0中将JPG格式图片转换成BMP格式思路:利用GDI+来完成难点:(1)配置GDI开发环境,添加配置代码(2)在当文档程序中添加转换代码注意:本文档由ybdesire参考网上资料撰写完成,代码已经做过测试,可直接复制张贴实现过程:一、配置GDI开发环境(1)下载GDI+ SDK for Visual C++ 6.0/code/legacy/gdi/GDIPlus.zip下载的GDIPlus文件夹中有Includes,Lib文件夹和gdiplus.dll文件。
将Includes和Lib中的文件分别拷到VC6安装目录中的VC98\include和lib文件夹中;新建MFC项目后,才使用gdiplus.dll,到时候将它拷到对应工程的debug 文件夹下。
(2)新建MFC单文档应用程序show:1、在StdAfx.h 中添加如下代码#include <afxdtctl.h>#define ULONG_PTR ULONG#include <gdiplus.h>using namespace Gdiplus;#pragma comment(lib, "gdiplus.lib")2、如(1)中所说,将gdiplus.dll拷贝到本工程的Debug或Release目录下3、在show.h中的class CShowApp : public CWinApp中添加private:GdiplusStartupInput m_gdiplusStartupInput;ULONG_PTR m_pGdiToken;4、在show.cpp中的BOOL CShowApp::InitInstance()中添加GdiplusStartup(&m_pGdiToken,&m_gdiplusStartupInput,NULL);5、为CShow App添加名字为ExitInstance的虚函数的,并在ExitInstance中添加如下退出GDI+的代码GdiplusShutdown(m_pGdiToken);return CWinApp::ExitInstance();(3)测试GDI+是否配置成功void CShowView::OnDraw(CDC* pDC){CShowDoc* pDoc = GetDocument();ASSERT_VALID(pDoc);Graphics graphics(pDC->m_hDC);Pen pen(Color(255, 0, 255));graphics.DrawLine(&pen, 0, 0, 200, 100);}若能成功运行,表明GDI+配置成功二、添加转换代码,实现将打开的JPG格式文件保存成BMP格式文件(1)在CSshowView中添加如下成员变量CString strOpenFileName;(2)在CSshowView中添加如下成员函数1、在CSshowView中添加ToWChar函数WCHAR* CShowView::ToWChar(char *str){//在GDI+中,有关字符的参数类型全部都是WCHAR类型的//该函数是将传统字符串进行转换static WCHAR buffer[1024];wcsset(buffer,0);MultiByteToWideChar(CP_ACP,0,str,strlen(str),buffer,1024);return buffer;}2、在CSshowView中添加GetImageCLSID函数int CShowView::GetImageCLSID(const WCHAR *format, CLSID *pCLSID) {UINT num=0;UINT size=0;ImageCodecInfo* pImageCodecInfo=NULL;GetImageEncodersSize(&num,&size);if(size==0)return FALSE; // 编码信息不可用// 分配内存pImageCodecInfo=(ImageCodecInfo*)(malloc(size));if(pImageCodecInfo==NULL)return FALSE; // 分配失败// 获得系统中可用的编码方式的所有信息GetImageEncoders(num,size,pImageCodecInfo);// 在可用编码信息中查找 format 格式是否被支持for(UINT i=0;i<num;++i){//MimeType: 编码方式的具体描述if (wcscmp(pImageCodecInfo[ i] .MimeType,format)==0){*pCLSID=pImageCodecInfo[i].Clsid;free(pImageCodecInfo);return TRUE;}}free(pImageCodecInfo);return FALSE;}3、在MFC ClassWixard中重载OnFileOpen()void CShowView::OnFileOpen(){static char szFilter[ ]="常见图像格式文件(*.*)|*.*|";CFileDialogdlgChoseImage(1,NULL,NULL,NULL,szFilter);if(dlgChoseImage.DoModal() ==IDOK){strOpenFileName=dlgChoseImage.GetPathName();// 打开文件后立即在窗口中显示 (重绘客户窗口)this->Invalidate() ;}}4、在MFC ClassWixard中重载OnFileSave()void CShowView::OnFileSave(){if( strOpenFileName.IsEmpty() ){AfxMessageBox("当前没有打开图像文件, 不能进行保存!");return;}// 建立图形对象Graphics graphics(GetDC()->m_hDC);// 装入当前已经打开的图像文件Imageimage(ToWChar(strOpenFileName.GetBuffer(strOpenFileName.GetLength() ) ));CString strFileSave;// 将其他格式的图像全部另存为 BMP 文件static char szFilter[ ]= "位图(*.BMP)|*.BMP|";CFileDialogdlgChoseImage(0,"BMP",strOpenFileName,NULL,szFilter);if(dlgChoseImage.DoModal() ==IDOK){strFileSave=dlgChoseImage.GetPathName();CLSID clsid;if(GetImageCLSID(L"image/bmp", &clsid)){image.Save(ToWChar(strFileSave.GetBuffer(strFileSave.GetLength() )), &clsid, NULL);// 将保存后的图像进行显示strOpenFileName=strFileSave;this->Invalidate() ;}}}参考资料[1]/poonjun/archive/2009/01/04/3701724.aspx[2]/DavidHu/articles/1191635.html[3]/bbsgcon.php?board=VisualC&num=785[4]《图像格式转换在数字仪表识别系统中的应用》刘娜, 汪仁煌, 庞然/*-------------------------------------------------------------*/扩展知识阅读[3] 色彩鲜艳漂亮的高品质图像,一个个形象的Windows图标,高速运动、活灵活现的三维动画,这些生动的图形无一不显示着程序设计者的艺术才华。
在VC++中如何将绘制的图形存储成位图 太匆匆忙 2009-12-16 14:19:04 124.164.196.* 您好CClientDC dc(this);//取得客户区内存DC
CDC THDC;HBITMAP THBM;THDC.CreateCompatibleDC(0);//创建相关场景THBM=(HBITMAP)LoadImage(NULL,"D:\\x.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE|LR_CREATEDIBSECTION);//载入位图BITMAP bmp;GetObject(THBM,sizeof(bmp),&bmp);//取得位图信息SelectObject(THDC,THBM);//选入位图至内存DCDeleteObject(THBM);//删除位图
BitBlt(dc,0,0,bmp.bmWidth,bmp.bmHeight,THDC,0,0,SRCCOPY);//将临时内存DC中的位图画到客户区中
//首先在D盘根目录下放一个标准.bmp格式的位图 再将这些代码写入一个按钮事件中 点击按键 就会在窗体的左上角看到图形了.
calpt 2009-12-26 18:03:43 116.205.254.*
Visual C++ MFC中没有提供一个专门的类来处理DIB位图,因此,为了方便地使用位图文件,我们有必要派生一个CDib类。类的源代码如下:
(1) CDib类的声明// DIB.h:类CDib声明头文件#ifndef __DIB_H__#define __DIB_H__#include <wingdi.h>class CDib{ public: CDib(); ~CDib();
BOOL Load( const char * ); BOOL Save( const char * ); BOOL Draw( CDC *, int nX = 0, int nY = 0, int nWidth = -1, int nHeight = -1, int mode = SRCCOPY);
BOOL SetPalette( CDC * );
private: CPalette m_Palette; unsigned char *m_pDib, *m_pDibBits; DWORD m_dwDibSize; BITMAPINFOHEADER *m_pBIH; RGBQUAD *m_pPalette; int m_nPaletteEntries;};#endif
(2) CDib类的实现// DIB.cpp:类CDib实现文件#include "stdafx.h"#include "DIB.h"
CDib::CDib(){ m_pDib = NULL;}
CDib::~CDib(){ // 如果位图已经被加载,释放内存 if (m_pDib != NULL) delete []m_pDib;}
下面这个函数非常重要,其功能为加载位图,类似于CBitmap类的LoadBitmap函数:
BOOL CDib::Load(const char *pszFilename){ CFile cf;
// 打开位图文件 if (!cf.Open(pszFilename, CFile::modeRead)) return (FALSE);
// 获得位图文件大小,并减去BITMAPFILEHEADER的长度 DWORD dwDibSize; dwDibSize = cf.GetLength() - sizeof(BITMAPFILEHEADER);
// 为DIB位图分配内存 unsigned char *pDib; pDib = new unsigned char[dwDibSize]; if (pDib == NULL) return (FALSE);
BITMAPFILEHEADER BFH; // 读取位图文件数据 try { // 文件格式是否正确有效 if ( cf.Read(&BFH, sizeof(BITMAPFILEHEADER)) != sizeof(BITMAPFILEHEADER) ||
BFH.bfType != ’MB’ || cf.Read(pDib, dwDibSize) != dwDibSize) { delete []pDib; return (FALSE); } } catch (CFileException *e) { e->Delete(); delete []pDib; return (FALSE); }
// delete先前加载的位图 if (m_pDib != NULL) delete m_pDib;
// 将临时Dib数据指针和Dib大小变量赋给类成员变量 m_pDib = pDib; m_dwDibSize = dwDibSize;
// 为相应类成员变量赋BITMAPINFOHEADER和调色板指针 m_pBIH = (BITMAPINFOHEADER*)m_pDib; m_pPalette = (RGBQUAD*) &m_pDib[sizeof(BITMAPINFOHEADER)];
// 计算调色板中实际颜色数量 m_nPaletteEntries = 1 << m_pBIH->biBitCount; if (m_pBIH->biBitCount > 8) m_nPaletteEntries = 0; else if (m_pBIH->biClrUsed != 0) m_nPaletteEntries = m_pBIH->biClrUsed;
// 为相应类成员变量赋image data指针 m_pDibBits = &m_pDib[sizeof(BITMAPINFOHEADER) + m_nPaletteEntries * sizeof (RGBQUAD)];
// delete先前的调色板 if (m_Palette.GetSafeHandle() != NULL) m_Palette.DeleteObject();
// 如果位图中存在调色板,创建LOGPALETTE 及CPalette if (m_nPaletteEntries != 0) { LOGPALETTE *pLogPal = (LOGPALETTE*)new char[sizeof(LOGPALETTE) + m_nPaletteEntries *sizeof(PALETTEENTRY)]; if (pLogPal != NULL) { pLogPal->palVersion = 0x300; pLogPal->palNumEntries = m_nPaletteEntries;
for (int i = 0; i < m_nPaletteEntries; i++) { pLogPal->palPalEntry[i].peRed = m_pPalette[i].rgbRed; pLogPal->palPalEntry[i].peGreen = m_pPalette[i].rgbGreen; pLogPal->palPalEntry[i].peBlue = m_pPalette[i].rgbBlue; }
//创建CPalette并释放LOGPALETTE的内存 m_Palette.CreatePalette(pLogPal); delete []pLogPal; } }
return (TRUE);}//函数功能:保存位图入BMP文件BOOL CDib::Save(const char *pszFilename){ if (m_pDib == NULL) return (FALSE);
CFile cf; if (!cf.Open(pszFilename, CFile::modeCreate | CFile::modeWrite)) return (FALSE);
try { BITMAPFILEHEADER BFH; memset(&BFH, 0, sizeof(BITMAPFILEHEADER)); BFH.bfType = ’MB’; BFH.bfSize = sizeof(BITMAPFILEHEADER) + m_dwDibSize; BFH.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + m_nPaletteEntries *sizeof(RGBQUAD); cf.Write(&BFH, sizeof(BITMAPFILEHEADER)); cf.Write(m_pDib, m_dwDibSize); } catch (CFileException *e) { e->Delete(); return (FALSE); } return (TRUE);}
下面这个函数也非常重要,其功能为在pDC指向的CDC中绘制位图,起点坐标为(nX,nY),绘制宽度和高度为nWidth、nHeight,最后一个参数是光栅模式:
BOOL CDib::Draw(CDC *pDC, int nX, int nY, int nWidth, int nHeight, int mode){ if (m_pDib == NULL)