if( bytes>widthBytes ) bytes = widthBytes; for(i=0;i
(7) Bmp文件保存函数
BOOL SDImage::SaveBitmap(CString a_Filename) { if( !IsValid() ) return FALSE; FILE *pf = fopen(a_Filename,\ if( pf==NULL ) return FALSE; BITMAPINFO *pbmi; pbmi = (BITMAPINFO*)calloc(1, sizeof(BITMAPINFOHEADER)); pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); pbmi->bmiHeader.biWidth = m_Width; pbmi->bmiHeader.biHeight = m_Height; pbmi->bmiHeader.biPlanes = 1; pbmi->bmiHeader.biBitCount = 24;
pbmi->bmiHeader.biCompression = BI_RGB; UINT widthBytes = ((m_Width * 24 +31)/32)*4;
pbmi->bmiHeader.biSizeImage = widthBytes * m_Height; pbmi->bmiHeader.biXPelsPerMeter = 11810; pbmi->bmiHeader.biYPelsPerMeter = 11810; pbmi->bmiHeader.biClrUsed = 0; pbmi->bmiHeader.biClrImportant = 0;
BITMAPFILEHEADER hdr; BITMAPINFOHEADER *pbih;
pbih = (BITMAPINFOHEADER*)pbmi;
hdr.bfType = 0x4d42; // 0x42 = \
hdr.bfSize = (DWORD) (sizeof(BITMAPFILEHEADER) + pbih->biSize + pbih->biSizeImage); hdr.bfReserved1 = 0;
hdr.bfReserved2 = 0;
hdr.bfOffBits = (DWORD) sizeof(BITMAPFILEHEADER) + pbih->biSize; fwrite(&hdr, sizeof(BITMAPFILEHEADER), 1, pf); fwrite(pbih, sizeof(BITMAPINFOHEADER), 1, pf); int i; BYTE *p1; for(i=m_Height-1;i>=0;i--) { p1 = m_pBits + m_WidthBytes * i; if( fwrite(p1, 1, widthBytes, pf) != widthBytes ) { free((HLOCAL)pbmi); fclose(pf); return FALSE; } } free((HLOCAL)pbmi); fclose(pf); return TRUE; }
4. 组建程序
在SDImage.cpp处于当前编辑窗口时,点击菜单“组建—编译”,或点击相应的工具栏图标,对SDImage.cpp进行编译。在VC主界面下侧的组合窗口中将显示编译的状态。当编译中出现错误时,按F4键将依次定位到源程序的错误处,请检查并改正错误。
第四节 定义图像文档实现图像读/写
1. 添加头文件
在DIPJQ.h文件中添加如下一行代码:(其中灰色部分为程序中已有的代码,后同) #include \ // main symbols #include \
2. 定义图像类指针
在DIPJQDoc.h文件中添加如下一行代码: // Attributes public:
class SDImage *m_pCurImage,*m_pLastImage;
注:定义两个图像类的指针,以使程序具备对最近一次处理的恢复功能。
3. 图像对象的建立和释放
在“ClassView”选项页中,点击展开“CDIPJQDoc”,双击“CDIPJQDoc()”,打开DIPJQDoc.cpp文件,在文件中修改添加如下代码: CDIPJQDoc::CDIPJQDoc() { }
CDIPJQDoc::~CDIPJQDoc() { }
delete m_pCurImage; delete m_pLastImage;
4. 进行消息映射
点击菜单“查看—建立类向导”,打开“MFC ClassWizard”对话框(Ctrl+w)。在“Class Name”下拉框中选中“CDIPJQDoc”,在“Object IDs”列表框中选中“CDIPJQDoc”,然后在“Messgaes”列表框中,选中“OnOpenDocument”并双击,建立起相应的消息映射函数;再选中“OnSaveDocument”双击。
// TODO: add one-time construction code here m_pCurImage = new SDImage; m_pLastImage = new SDImage;
在“Object IDs”列表框中选中“ID_EDIT_UNDO”,然后在“Message”列表框中双击“COMMAND”,建立起相应的消息映射函数。
5. 添加消息映射函数代码
在“ClassView”选项页中,点击展开“CDIPJQDoc”,双击“OnOpenDocument(LPCTSTR lpszPathName)”,打开DIPJQDoc.cpp文件,在文件中添加如下代码: BOOL CDIPJQDoc::OnOpenDocument(LPCTSTR lpszPathName) { if (!CDocument::OnOpenDocument(lpszPathName)) return FALSE; // TODO: Add your specialized creation code here return m_pCurImage->LoadBmpFile(lpszPathName); }
BOOL CDIPJQDoc::OnSaveDocument(LPCTSTR lpszPathName) { // TODO: Add your specialized code here and/or call the base class return m_pCurImage->SaveBitmap(lpszPathName); }
void CDIPJQDoc::OnEditUndo() { // TODO: Add your command handler code here if( m_pCurImage->IsValid() && m_pLastImage->IsValid() ) { SDImage *p = m_pCurImage; m_pCurImage = m_pLastImage; m_pLastImage = p;