VC++2010开发数字图像系统1

来源:互联网 发布:java包装类有啥用 编辑:程序博客网 时间:2024/06/15 06:42

VS2010编程小技巧:1.注意在文档类C..Doc中使用和在视图类C..View中使用MessageBox函数时的参数不相同,不要用错。2.创建与控件关联的指针变量时,一定要注意初始化,不要形成垂悬指针,否则会出现“烫烫烫烫..."”屯屯屯...的乱码。

这里我们利用自己的图像函数库去处理数字图像,在掌握基本方法和基本理论后再去结合OpenCV和matlab去实现算法。

  1. 新建一基于单文档的MFC应用程序(选择SDI单文档选项,其他选择默认)。
  2. 添加自己的类库(Dib.h和Dib.cpp两个文件)

  Dib.h

 

  1 //**************************************************  2 // Name:        Dib.h  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.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 }
View Code

    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 }
View Code

       5. Ctrl+F5运行

0 0
原创粉丝点击