VS2010编程小技巧:1.注意在文档类C..Doc中使用和在视图类C..View中使用MessageBox函数时的参数不相同,不要用错。2.创建与控件关联的指针变量时,一定要注意初始化,不要形成垂悬指针,否则会出现“烫烫烫烫..."”屯屯屯...的乱码。
这里我们利用自己的图像函数库去处理数字图像,在掌握基本方法和基本理论后再去结合OpenCV和matlab去实现算法。
- 新建一基于单文档的MFC应用程序(选择SDI单文档选项,其他选择默认)。
- 添加自己的类库(Dib.h和Dib.cpp两个文件)
Dib.h
1 //************************************************** 2 // Name: Dib.h 3 // Purpose: ImgPro 6 // Created: 2013/3/28 8 // Licence: 9 //*************************************************** 10 //====================================================================== 11 // 文件: Dib.h 12 // 内容: 设备无关位图类-头文件 13 // 功能: (1)位图的加载与保存; 14 // (2)位图信息的获取; 15 // (3)位图数据的获取; 16 // (3)位图的显示; 17 // (4)位图的转换; 18 // (5)位图相关判断; 19 //====================================================================== 20 21 #pragma once 22 23 #include "afx.h" 24 25 class CDib : public CObject 26 { 27 public: 28 // 构造函数,初始化数据成员 29 CDib(void); 30 31 // 析构函数,释放内存空间 32 ~CDib(void); 33 34 // 从文件加载位图 35 BOOL LoadFromFile(LPCTSTR lpszPath); 36 37 // 将位图保存到文件 38 BOOL SaveToFile(LPCTSTR lpszPath); 39 40 // 获取位图文件名 41 LPCTSTR GetFileName(); 42 43 // 获取位图宽度 44 LONG GetWidth(); 45 46 // 获取位图高度 47 LONG GetHeight(); 48 49 // 获取位图的宽度和高度 50 CSize GetDimension(); 51 52 // 获取位图大小 53 DWORD GetSize(); 54 55 // 获取单个像素所占位数 56 WORD GetBitCount(); 57 58 // 获取每行像素所占字节数 59 UINT GetLineByte(); 60 61 // 获取位图颜色数 62 DWORD GetNumOfColor(); 63 64 // 获取位图颜色表 65 LPRGBQUAD GetRgbQuad(); 66 67 // 获取位图数据 68 LPBYTE GetData(); 69 70 // 显示位图 71 BOOL Draw(CDC *pDC, CPoint origin, CSize size); 72 73 // 24位彩色位图转8位灰度位图 74 BOOL RgbToGrade(); 75 76 // 8位灰度位图转24位彩色位图 77 BOOL GradeToRgb(); 78 79 // 判断是否含有颜色表 80 BOOL HasRgbQuad(); 81 82 // 判断是否是灰度图 83 BOOL IsGrade(); 84 85 // 判断位图是否有效 86 BOOL IsValid(); 87 88 protected: 89 // 计算位图颜色表长度 90 DWORD CalcRgbQuadLength(); 91 92 // 根据颜色表生成调色板 93 BOOL MakePalette(); 94 95 // 清理空间 96 void Empty(BOOL bFlag = TRUE); 97 98 private: 99 // 位图文件名100 CString m_fileName;101 102 // 位图文件头指针 103 LPBITMAPFILEHEADER m_lpBmpFileHeader; // 需要动态分配和释放 104 105 // 位图指针(包含除位图文件头的所有内容)106 LPBYTE m_lpDib; // 需要动态分配和释放107 108 // 位图信息指针109 LPBITMAPINFO m_lpBmpInfo;110 111 // 位图信息头指针112 LPBITMAPINFOHEADER m_lpBmpInfoHeader; 113 114 // 位图颜色表指针115 LPRGBQUAD m_lpRgbQuad; 116 117 // 位图数据指针118 LPBYTE m_lpData; 119 120 // 调色板句柄121 HPALETTE m_hPalette;122 123 // 是否有颜色表124 BOOL m_bHasRgbQuad;125 126 // 位图是否有效127 BOOL m_bValid;128 };
Dib.cpp
1 //************************************************** 2 // Name: Dib.cpp 3 // Purpose: ImgPro 4 // Author: sxzheng@live.cn 5 // Modified by: sxzheng@live.cn 6 // Created: 2013/3/28 7 // Copyright: (c)sxzheng@live.cn 8 // Licence: 9 //*************************************************** 10 //*************************************************** 11 // 文件: Dib.cpp 12 // 内容: 设备无关位图类-源文件 13 // 功能: (1)位图的加载与保存; 14 // (2)位图信息的获取; 15 // (3)位图数据的获取; 16 // (3)位图的显示; 17 // (4)位图的转换; 18 // (5)位图相关判断; 19 //*************************************************** 20 21 #include "StdAfx.h" 22 #include "Dib.h" 23 24 //*************************************************** 25 // 函数功能: 构造函数,初始化数据成员 26 // 输入参数: 无 27 // 返回值: 无 28 //*************************************************** 29 CDib::CDib(void) 30 { 31 // 数据成员初始化 32 m_fileName=""; 33 m_lpBmpFileHeader = NULL; 34 m_lpDib = NULL; 35 m_lpBmpInfo = NULL; 36 m_lpBmpInfoHeader = NULL; 37 m_lpRgbQuad = NULL; 38 m_lpData = NULL; 39 m_hPalette = NULL; 40 m_bHasRgbQuad = FALSE; 41 m_bValid = FALSE; 42 } 43 44 //*************************************************** 45 // 函数功能: 析构函数,释放内存空间 46 // 输入参数: 无 47 // 返回值: 无 48 //*************************************************** 49 CDib::~CDib(void) 50 { 51 // 清理空间 52 Empty(); 53 } 54 55 //*************************************************** 56 // 函数功能: 从文件加载位图 57 // 输入参数: LPCTSTR lpszPath-待加载位图文件路径 58 // 返回值: BOOL-TRUE 成功;FALSE 失败 59 //*************************************************** 60 BOOL CDib::LoadFromFile(LPCTSTR lpszPath) 61 { 62 // 记录位图文件名 63 m_fileName=lpszPath; 64 65 // 以读模式打开位图文件 66 CFile dibFile; 67 if(!dibFile.Open(m_fileName, CFile::modeRead | CFile::shareDenyWrite)) 68 { 69 return FALSE; 70 } 71 72 // 清理空间 73 Empty(FALSE); 74 75 // 为位图文件头分配空间,并初始化为0 76 m_lpBmpFileHeader = (LPBITMAPFILEHEADER)new BYTE[sizeof(BITMAPFILEHEADER)]; 77 memset(m_lpBmpFileHeader, 0, sizeof(BITMAPFILEHEADER)); 78 79 // 读取位图文件头 80 int nCount = dibFile.Read((void *)m_lpBmpFileHeader, sizeof(BITMAPFILEHEADER)); 81 if(nCount != sizeof(BITMAPFILEHEADER)) 82 { 83 return FALSE; 84 } 85 86 // 判断此文件是不是位图文件(“0x4d42”代表“BM”) 87 if(m_lpBmpFileHeader->bfType == 0x4d42) 88 { 89 // 是位图文件 90 91 // 计算除位图文件头的空间大小,分配空间并初始化为0 92 DWORD dwDibSize = dibFile.GetLength() - sizeof(BITMAPFILEHEADER); 93 m_lpDib = new BYTE[dwDibSize]; 94 memset(m_lpDib, 0, dwDibSize); 95 96 // 读取除位图文件头的所有数据 97 dibFile.Read(m_lpDib, dwDibSize); 98 99 // 关闭位图文件100 dibFile.Close();101 102 // 设置位图信息指针103 m_lpBmpInfo = (LPBITMAPINFO)m_lpDib;104 105 // 设置位图信息头指针106 m_lpBmpInfoHeader = (LPBITMAPINFOHEADER)m_lpDib;107 108 // 设置位图颜色表指针109 m_lpRgbQuad = (LPRGBQUAD)(m_lpDib + m_lpBmpInfoHeader->biSize);110 111 // 如果位图没有设置位图使用的颜色数,设置它112 if(m_lpBmpInfoHeader->biClrUsed == 0)113 {114 m_lpBmpInfoHeader->biClrUsed = GetNumOfColor();115 }116 117 // 计算颜色表长度118 DWORD dwRgbQuadLength = CalcRgbQuadLength();119 120 // 设置位图数据指针121 m_lpData = m_lpDib + m_lpBmpInfoHeader->biSize + dwRgbQuadLength;122 123 // 判断是否有颜色表124 if(m_lpRgbQuad == (LPRGBQUAD)m_lpData)125 {126 m_lpRgbQuad = NULL; // 将位图颜色表指针置空127 m_bHasRgbQuad = FALSE; // 无颜色表128 }129 else130 {131 m_bHasRgbQuad = TRUE; // 有颜色表132 MakePalette(); // 根据颜色表生成调色板133 } 134 135 // 设置位图大小(因为很多位图文件都不设置此项)136 m_lpBmpInfoHeader->biSizeImage = GetSize();137 138 // 位图有效139 m_bValid = TRUE;140 141 return TRUE;142 }143 else144 {145 // 不是位图文件146 m_bValid = FALSE;147 148 return FALSE;149 } 150 151 }152 153 //***************************************************154 // 函数功能: 将位图保存到文件155 // 输入参数: LPCTSTR lpszPath-位图文件保存路径156 // 返回值: BOOL-TRUE 成功;FALSE 失败157 //***************************************************158 BOOL CDib::SaveToFile(LPCTSTR lpszPath)159 {160 // 以写模式打开文件161 CFile dibFile;162 if(!dibFile.Open(lpszPath, CFile::modeCreate | CFile::modeReadWrite 163 | CFile::shareExclusive))164 {165 return FALSE;166 }167 168 // 记录位图文件名169 m_fileName=lpszPath;170 171 // 将文件头结构写进文件172 dibFile.Write(m_lpBmpFileHeader, sizeof(BITMAPFILEHEADER));173 174 // 将文件信息头结构写进文件175 dibFile.Write(m_lpBmpInfoHeader, sizeof(BITMAPINFOHEADER));176 177 // 计算颜色表长度178 DWORD dwRgbQuadlength = CalcRgbQuadLength();179 180 // 如果有颜色表的话,将颜色表写进文件181 if(dwRgbQuadlength != 0)182 {183 dibFile.Write(m_lpRgbQuad, dwRgbQuadlength);184 } 185 186 // 将位图数据写进文件187 DWORD dwDataSize = GetLineByte() * GetHeight();188 dibFile.Write(m_lpData, dwDataSize);189 190 // 关闭文件191 dibFile.Close();192 193 return TRUE;194 }195 196 //***************************************************197 // 函数功能: 获取位图文件名198 // 输入参数: 无199 // 返回值: LPCTSTR-位图文件名200 //***************************************************201 LPCTSTR CDib::GetFileName()202 {203 return m_fileName;204 }205 206 //***************************************************207 // 函数功能: 获取位图宽度208 // 输入参数: 无209 // 返回值: LONG-位图宽度210 //***************************************************211 LONG CDib::GetWidth()212 {213 return m_lpBmpInfoHeader->biWidth;214 }215 216 //***************************************************217 // 函数功能: 获取位图高度218 // 输入参数: 无219 // 返回值: LONG-位图高度220 //***************************************************221 LONG CDib::GetHeight()222 {223 return m_lpBmpInfoHeader->biHeight;224 }225 226 //***************************************************227 // 函数功能: 获取位图的宽度和高度228 // 输入参数: 无229 // 返回值: CSize-位图的宽度和高度230 //***************************************************231 CSize CDib::GetDimension()232 {233 return CSize(GetWidth(), GetHeight());234 }235 236 //***************************************************237 // 函数功能: 获取位图大小238 // 输入参数: 无239 // 返回值: DWORD-位图大小240 //***************************************************241 DWORD CDib::GetSize()242 {243 if(m_lpBmpInfoHeader->biSizeImage != 0)244 {245 return m_lpBmpInfoHeader->biSizeImage;246 }247 else248 { 249 return GetWidth() * GetHeight();250 }251 }252 253 //***************************************************254 // 函数功能: 获取单个像素所占位数255 // 输入参数: 无256 // 返回值: WORD-单个像素所占位数257 //***************************************************258 WORD CDib::GetBitCount()259 {260 return m_lpBmpInfoHeader->biBitCount;261 } 262 263 //***************************************************264 // 函数功能: 获取每行像素所占字节数265 // 输入参数: 无266 // 返回值: UINT-每行像素所占字节数267 //***************************************************268 UINT CDib::GetLineByte()269 { 270 return (GetWidth() * GetBitCount() / 8 + 3) / 4 * 4;;271 }272 273 //***************************************************274 // 函数功能: 获取位图颜色数275 // 输入参数: 无276 // 返回值: DWORD-位图颜色数277 //***************************************************278 DWORD CDib::GetNumOfColor()279 {280 UINT dwNumOfColor; 281 282 if ((m_lpBmpInfoHeader->biClrUsed == 0) 283 && (m_lpBmpInfoHeader->biBitCount < 9))284 {285 switch (m_lpBmpInfoHeader->biBitCount)286 {287 case 1: dwNumOfColor = 2; break;288 case 4: dwNumOfColor = 16; break;289 case 8: dwNumOfColor = 256;290 }291 }292 else293 {294 dwNumOfColor = m_lpBmpInfoHeader->biClrUsed;295 } 296 297 return dwNumOfColor; 298 }299 300 //***************************************************301 // 函数功能: 计算位图颜色表长度302 // 输入参数: 无303 // 返回值: DWORD-位图颜色表长度304 //***************************************************305 DWORD CDib::CalcRgbQuadLength()306 {307 DWORD dwNumOfColor = GetNumOfColor();308 if(dwNumOfColor > 256)309 {310 dwNumOfColor = 0;311 }312 return dwNumOfColor * sizeof(RGBQUAD);313 }314 315 //***************************************************316 // 函数功能: 获取位图颜色表317 // 输入参数: 无318 // 返回值: LPRGBQUAD-位图颜色表指针319 //***************************************************320 LPRGBQUAD CDib::GetRgbQuad()321 {322 return m_lpRgbQuad;323 }324 325 //***************************************************326 // 函数功能: 获取位图数据327 // 输入参数: 无328 // 返回值: LPBYTE-位图数据指针329 //***************************************************330 LPBYTE CDib::GetData()331 {332 return m_lpData;333 }334 335 //***************************************************336 // 函数功能: 根据颜色表生成调色板337 // 输入参数: 无338 // 返回值: BOOL-TRUE 成功;FALSE 失败339 //***************************************************340 BOOL CDib::MakePalette()341 {342 // 计算颜色表长度343 DWORD dwRgbQuadLength = CalcRgbQuadLength();344 345 // 如果颜色表长度为0,则不生成逻辑调色板346 if(dwRgbQuadLength == 0) 347 {348 return FALSE;349 }350 351 //删除旧的调色板对象352 if(m_hPalette != NULL) 353 {354 DeleteObject(m_hPalette);355 m_hPalette = NULL;356 }357 358 // 申请缓冲区,初始化为0359 DWORD dwNumOfColor = GetNumOfColor();360 DWORD dwSize = 2 * sizeof(WORD) + dwNumOfColor * sizeof(PALETTEENTRY);361 LPLOGPALETTE lpLogPalette = (LPLOGPALETTE) new BYTE[dwSize];362 memset(lpLogPalette, 0, dwSize);363 364 // 生成逻辑调色板365 lpLogPalette->palVersion = 0x300;366 lpLogPalette->palNumEntries = dwNumOfColor;367 LPRGBQUAD lpRgbQuad = (LPRGBQUAD) m_lpRgbQuad;368 for(int i = 0; i < dwNumOfColor; i++) 369 {370 lpLogPalette->palPalEntry[i].peRed = lpRgbQuad->rgbRed;371 lpLogPalette->palPalEntry[i].peGreen = lpRgbQuad->rgbGreen;372 lpLogPalette->palPalEntry[i].peBlue = lpRgbQuad->rgbBlue;373 lpLogPalette->palPalEntry[i].peFlags = 0;374 lpRgbQuad++;375 }376 377 // 创建逻辑调色板378 m_hPalette = CreatePalette(lpLogPalette);379 380 // 释放缓冲区381 delete [] lpLogPalette;382 383 return TRUE;384 }385 386 //***************************************************387 // 函数功能: 显示位图388 // 输入参数:389 // CDC *pDC-设备环境指针390 // CPoint origin-显示矩形区域的左上角391 // CSize size-显示矩形区域的尺寸392 // 返回值:393 // BOOL-TRUE 成功;FALSE 失败394 //***************************************************395 BOOL CDib::Draw(CDC *pDC, CPoint origin, CSize size)396 {397 // 位图无效,无法绘制,返回错误398 if(!IsValid())399 {400 return FALSE;401 }402 403 // 旧的调色板句柄404 HPALETTE hOldPalette = NULL;405 406 // 如果位图指针为空,则返回FALSE407 if(m_lpDib == NULL) 408 {409 return FALSE;410 }411 412 // 如果位图有调色板,则选进设备环境中413 if(m_hPalette != NULL) 414 {415 hOldPalette = SelectPalette(pDC->GetSafeHdc(), m_hPalette, TRUE);416 }417 418 // 设置位图伸缩模式419 pDC->SetStretchBltMode(COLORONCOLOR);420 421 // 将位图在pDC所指向的设备上进行显示422 StretchDIBits(pDC->GetSafeHdc(), origin.x, origin.y, size.cx, size.cy,423 0, 0, GetWidth(), GetHeight(), m_lpData, m_lpBmpInfo, DIB_RGB_COLORS, SRCCOPY);424 425 // 恢复旧的调色板426 if(hOldPalette != NULL)427 {428 SelectPalette(pDC->GetSafeHdc(), hOldPalette, TRUE);429 }430 431 return TRUE;432 }433 434 //***************************************************435 // 函数功能: 24位彩色位图转8位灰度位图436 // 输入参数: 无437 // 返回值: BOOL-TRUE 成功;FALSE 失败438 //***************************************************439 BOOL CDib::RgbToGrade()440 {441 // 位图无效,失败返回442 if(!IsValid())443 {444 return FALSE;445 }446 447 // 不是24位位图,失败返回448 if(GetBitCount() != 24)449 {450 return FALSE;451 }452 453 // 是压缩位图,失败返回454 if(m_lpBmpInfoHeader->biCompression != BI_RGB)455 {456 return FALSE;457 }458 459 // 如果不是灰度位图,才需要转换460 if(!IsGrade())461 {462 // 获取原位图信息463 LONG lHeight = GetHeight();464 LONG lWidth = GetWidth();465 UINT uLineByte = GetLineByte();466 467 // 计算灰度位图数据所需空间468 UINT uGradeBmpLineByte = (lWidth + 3) / 4 * 4;469 DWORD dwGradeBmpDataSize = uGradeBmpLineByte * lHeight; 470 471 // 计算灰度位图所需空间472 DWORD dwGradeBmpSize = sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * 256 + dwGradeBmpDataSize;473 474 // 设置灰度位图文件头475 LPBITMAPFILEHEADER lpGradeBmpFileHeader = (LPBITMAPFILEHEADER)new BYTE[sizeof(BITMAPFILEHEADER)];476 memset(lpGradeBmpFileHeader, 0, sizeof(BITMAPFILEHEADER));477 lpGradeBmpFileHeader->bfType = 0x4d42;478 lpGradeBmpFileHeader->bfSize = sizeof(BITMAPFILEHEADER) + dwGradeBmpSize;479 lpGradeBmpFileHeader->bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER)480 + sizeof(RGBQUAD) * 256;481 lpGradeBmpFileHeader->bfReserved1 = 0;482 lpGradeBmpFileHeader->bfReserved2 = 0; 483 484 // 为灰度位图分配空间,并初始化为0485 LPBYTE lpGradeBmp = (LPBYTE)new BYTE[dwGradeBmpSize];486 memset(lpGradeBmp, 0, dwGradeBmpSize);487 488 // 设置灰度位图信息头489 LPBITMAPINFOHEADER lpGradeBmpInfoHeader = (LPBITMAPINFOHEADER)(lpGradeBmp);490 lpGradeBmpInfoHeader->biBitCount = 8;491 lpGradeBmpInfoHeader->biClrImportant = 0;492 lpGradeBmpInfoHeader->biClrUsed = 256;493 lpGradeBmpInfoHeader->biCompression = BI_RGB;494 lpGradeBmpInfoHeader->biHeight = lHeight;495 lpGradeBmpInfoHeader->biPlanes = 1;496 lpGradeBmpInfoHeader->biSize = sizeof(BITMAPINFOHEADER);497 lpGradeBmpInfoHeader->biSizeImage = dwGradeBmpDataSize;498 lpGradeBmpInfoHeader->biWidth = lWidth;499 lpGradeBmpInfoHeader->biXPelsPerMeter = m_lpBmpInfoHeader->biXPelsPerMeter;500 lpGradeBmpInfoHeader->biYPelsPerMeter = m_lpBmpInfoHeader->biYPelsPerMeter;501 502 // 设置灰度位图颜色表503 LPRGBQUAD lpGradeBmpRgbQuad = (LPRGBQUAD)(lpGradeBmp + sizeof(BITMAPINFOHEADER));504 505 // 初始化8位灰度图的调色板信息506 LPRGBQUAD lpRgbQuad; 507 for(int k = 0; k < 256; k++)508 {509 lpRgbQuad = (LPRGBQUAD)(lpGradeBmpRgbQuad + k);510 lpRgbQuad->rgbBlue = k; 511 lpRgbQuad->rgbGreen = k;512 lpRgbQuad->rgbRed = k;513 lpRgbQuad->rgbReserved = 0;514 }515 516 // 灰度位图数据处理517 BYTE r, g, b; 518 LPBYTE lpGradeBmpData = (LPBYTE)(lpGradeBmp + sizeof(BITMAPINFOHEADER) 519 + sizeof(RGBQUAD) * 256);520 // 进行颜色转换521 for(int i = 0; i < lHeight; i++)522 {523 for(int j = 0; j < lWidth; j++)524 {525 b = m_lpData[i * uLineByte + 3 * j];526 g = m_lpData[i * uLineByte + 3 * j + 1];527 r = m_lpData[i * uLineByte + 3 * j + 2];528 lpGradeBmpData[i * uGradeBmpLineByte + j] = (BYTE)(0.299 * r + 0.587 * g + 0.114 * b); 529 }530 }531 532 // 释放原有位图空间533 Empty(FALSE);534 535 // 重新设定原位图指针指向536 m_lpBmpFileHeader = lpGradeBmpFileHeader;537 m_lpDib = lpGradeBmp;538 m_lpBmpInfo = (LPBITMAPINFO)(lpGradeBmp);539 m_lpBmpInfoHeader = lpGradeBmpInfoHeader;540 m_lpRgbQuad = lpGradeBmpRgbQuad;541 m_lpData = lpGradeBmpData;542 543 // 设置颜色表标志544 m_bHasRgbQuad = TRUE; 545 // 设置位图有效标志546 m_bValid = TRUE;547 // 生成调色板548 MakePalette();549 }550 551 return TRUE; 552 } 553 554 //***************************************************555 // 函数功能: 8位灰度位图转24位彩色位图556 // 输入参数: 无557 // 返回值: BOOL-TRUE 成功;FALSE 失败558 //***************************************************559 BOOL CDib::GradeToRgb()560 {561 // 位图无效,失败退出562 if(!IsValid())563 {564 return FALSE;565 }566 567 // 不是8位位图,失败退出568 if(GetBitCount() != 8)569 {570 return FALSE;571 }572 573 // 是压缩位图,失败返回574 if(m_lpBmpInfoHeader->biCompression != BI_RGB)575 {576 return FALSE;577 }578 579 // 是灰度图时,才需转换580 if(IsGrade())581 {582 // 获取原位图信息583 LONG lHeight = GetHeight();584 LONG lWidth = GetWidth();585 UINT uLineByte = GetLineByte();586 587 // 计算彩色位图数据所需空间588 UINT uColorBmpLineByte = (lWidth * 24 / 8 + 3) / 4 * 4;589 DWORD dwColorBmpDataSize = uColorBmpLineByte * lHeight; 590 591 // 计算彩色位图所需空间592 DWORD dwColorBmpSize = sizeof(BITMAPINFOHEADER) + dwColorBmpDataSize;593 594 // 设置彩色位图文件头595 LPBITMAPFILEHEADER lpColorBmpFileHeader = (LPBITMAPFILEHEADER)new BYTE[sizeof(BITMAPFILEHEADER)];596 memset(lpColorBmpFileHeader, 0, sizeof(BITMAPFILEHEADER));597 lpColorBmpFileHeader->bfType = 0x4d42;598 lpColorBmpFileHeader->bfSize = sizeof(BITMAPFILEHEADER) + dwColorBmpSize;599 lpColorBmpFileHeader->bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);600 lpColorBmpFileHeader->bfReserved1 = 0;601 lpColorBmpFileHeader->bfReserved2 = 0; 602 603 // 为彩色位图分配空间,并初始化为0604 LPBYTE lpColorBmp = (LPBYTE)new BYTE[dwColorBmpSize];605 memset(lpColorBmp, 0, dwColorBmpSize);606 607 // 设置彩色位图信息头608 LPBITMAPINFOHEADER lpColorBmpInfoHeader = (LPBITMAPINFOHEADER)(lpColorBmp);609 lpColorBmpInfoHeader->biBitCount = 24;610 lpColorBmpInfoHeader->biClrImportant = 0;611 lpColorBmpInfoHeader->biClrUsed = 0;612 lpColorBmpInfoHeader->biCompression = BI_RGB;613 lpColorBmpInfoHeader->biHeight = lHeight;614 lpColorBmpInfoHeader->biPlanes = 1;615 lpColorBmpInfoHeader->biSize = sizeof(BITMAPINFOHEADER);616 lpColorBmpInfoHeader->biSizeImage = dwColorBmpDataSize;617 lpColorBmpInfoHeader->biWidth = lWidth;618 lpColorBmpInfoHeader->biXPelsPerMeter = m_lpBmpInfoHeader->biXPelsPerMeter;619 lpColorBmpInfoHeader->biYPelsPerMeter = m_lpBmpInfoHeader->biYPelsPerMeter;620 621 // 彩色位图数据处理622 LPBYTE lpColorBmpData = (LPBYTE)(lpColorBmp + sizeof(BITMAPINFOHEADER));623 // 进行颜色转换624 for(int i = 0; i < lHeight; i++)625 {626 for(int j = 0; j < lWidth; j++)627 {628 BYTE btValue = m_lpData[i * uLineByte + j]; 629 lpColorBmpData[i * uColorBmpLineByte + 3 * j] = btValue;630 lpColorBmpData[i * uColorBmpLineByte + 3 * j + 1] = btValue;631 lpColorBmpData[i * uColorBmpLineByte + 3 * j + 2] = btValue; 632 }633 }634 635 // 释放原有位图空间636 Empty(FALSE);637 638 // 重新设定原位图指针指向639 m_lpBmpFileHeader = lpColorBmpFileHeader;640 m_lpDib = lpColorBmp;641 m_lpBmpInfo = (LPBITMAPINFO)(lpColorBmp);642 m_lpBmpInfoHeader = lpColorBmpInfoHeader;643 m_lpRgbQuad = NULL;644 m_lpData = lpColorBmpData;645 646 // 设置颜色表标志647 m_bHasRgbQuad = FALSE; 648 // 设置位图有效标志649 m_bValid = TRUE; 650 } 651 652 return TRUE; 653 } 654 655 //***************************************************656 // 函数功能: 判断是否含有颜色表657 // 输入参数: 无658 // 返回值: 判断结果:TRUE-含有颜色表;FALSE-不含颜色表659 //***************************************************660 BOOL CDib::HasRgbQuad()661 {662 return m_bHasRgbQuad;663 }664 665 //***************************************************666 // 函数功能: 判断是否是灰度图667 // 输入参数: 无668 // 返回值: 判断结果:TRUE-是灰度图;FALSE-是彩色图669 //***************************************************670 BOOL CDib::IsGrade()671 {672 return (GetBitCount() < 9 && GetBitCount() > 0);673 }674 675 //***************************************************676 // 函数功能: 判断位图是否有效677 // 输入参数: 无678 // 返回值: 判断结果:TRUE-位图有效;FALSE-位图无效679 //***************************************************680 BOOL CDib::IsValid()681 {682 return m_bValid;683 }684 685 //***************************************************686 // 函数功能: 清理空间687 // 输入参数: BOOL bFlag-TRUE 全部清空;FALSE 部分清空688 // 返回值: 无689 //***************************************************690 void CDib::Empty(BOOL bFlag)691 {692 // 文件名清空693 if(bFlag)694 {695 m_fileName="";696 } 697 698 // 释放位图文件头指针空间699 if(m_lpBmpFileHeader != NULL)700 {701 delete [] m_lpBmpFileHeader;702 m_lpBmpFileHeader = NULL;703 } 704 705 // 释放位图指针空间706 if(m_lpDib != NULL)707 {708 delete [] m_lpDib;709 m_lpDib = NULL;710 m_lpBmpInfo = NULL;711 m_lpBmpInfoHeader = NULL;712 m_lpRgbQuad = NULL;713 m_lpData = NULL; 714 } 715 716 // 释放调色板717 if(m_hPalette != NULL)718 {719 DeleteObject(m_hPalette);720 m_hPalette = NULL;721 } 722 723 // 设置不含颜色表724 m_bHasRgbQuad = FALSE;725 726 // 设置位图无效727 m_bValid = FALSE;728 729 }
3.在CImgProDoc.h文件中,添加
public:
CDib dib;
// 生成的消息映射函数
protected: DECLARE_MESSAGE_MAP()//非添加语句 virtual BOOL OnOpenDocument(LPCTSTR lpszPathName);public: CDib* GetDib(void);在CImgProDoc.cpp中,实现上面添加的两个成员函数:
1 CDib* CImgProDoc::GetDib(void) 2 { 3 return &dib; 4 } 5 BOOL CImgProDoc::OnOpenDocument(LPCTSTR lpszPathName) 6 { 7 if(!CDocument::OnOpenDocument(lpszPathName)) 8 return FALSE; 9 if(!dib.LoadFromFile(lpszPathName))10 {11 AfxMessageBox(_T("加载位图失败!"));12 return FALSE;13 }14 return TRUE;15 }
4. 图像的显示
在CImgProView.cpp文件中将OnDraw函数修改如下:
1 // CImgProView 绘制 2 3 void CImgProView::OnDraw(CDC* pDC) 4 { 5 CImgProDoc* pDoc = GetDocument(); 6 ASSERT_VALID(pDoc); 7 if (!pDoc) 8 return; 9 10 // TODO: 在此处为本机数据添加绘制代码11 CDib *pDib=pDoc->GetDib();12 if(pDib->IsValid())13 {14 CSize size=pDib->GetDimension();15 pDib->Draw(pDC,CPoint(0,0),size);16 }17 }
5. Ctrl+F5运行