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  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         else
130         {
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     else
144     {
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     else
248     {
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     else
293     {
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     // 申请缓冲区,初始化为0
359     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     // 如果位图指针为空,则返回FALSE
407     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         // 为灰度位图分配空间,并初始化为0
485         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         // 为彩色位图分配空间,并初始化为0
604         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运行

转载于:https://www.cnblogs.com/sxzheng/archive/2013/03/29/sxzheng.html

VC++2010开发数字图像系统1相关推荐

  1. CSDN著名技术专家Visual C++2010开发体验心得——从Visual C++6.0到Visual C++2010见证VC++辉煌时刻

    分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! IT业是 ...

  2. PACS系统源码 PACS源码 基于VC + MSSQL开发

    基于VC + MSSQL开发的一套大型医院医学影像PACS系统源码,有演示.文末获取联系! PACS系统可以覆盖医院现有放射.CT.MR.核医学.超声.内镜.病理.心电等绝大部分DICOM和非DICO ...

  3. SharePoint 2010在WIN7系统下建立开发环境

    SharePoint 2010在WIN7系统下建立开发环境 (MSDN上有比较详细的介绍,地址:http://msdn.microsoft.com/en-us/library/ee554869%28o ...

  4. VC++2010基于windows Sdk for windows7 开发CrytoAPI应用--加密解密文件

    windows Sdk for windows7 开发CrytoAPI是微软推出的安全应用调用函数,用很小的代码就可以实现复杂的安全信息加密.下面演示文件加密解密,详情请见代码. #include & ...

  5. VS2008(2010)开发C++

    命令行执行vc的用法参见: http://blog.csdn.net/memory_xj/archive/2008/10/27/3156781.aspx VS 2008 找不到"window ...

  6. 复杂交联环境下的测试任务快速开发工具系统情况

    系统描述 1.拟选厂商简介 凯云联创(北京)科技有限公司(简称:凯云科技)成立于2014年,核心业务是为军方.航空航天.中电.兵器.船舶.核工业.核物理.院校.交通.水利水电.通信以及金融等行业提供软 ...

  7. CSDN著名技术专家Visual C++2010开发体验心得——从Visual C++6 0到Visual C++201

    IT业是一个创造奇迹的行业,IT业也是一个年轻的行业,IT业更是一个不断更新的行业.在2009年,微软已经连续推出Visual Studio2010 beta1 与 Visual Studio2010 ...

  8. Win7旗舰开发版—系统

    此SYS.GGH镜像文件是由Windows7一键还原生成. 本系统为正版Windows7旗舰版系统(三星) 内置常用软件: IE9微软最新的浏览器 正版Office2010全部的办公软件(已激活) A ...

  9. java判断点与线与面的关系_VC++开发GIS系统(280)判断点与面的拓扑关系

    本文介绍GIS系统中,点与面之间拓扑关系的判断方法. 关于点面之间的拓扑 通常情况下可以将点与面的关系做如下划分: 点在面内 点在面的边界上 点在面外 本文做了一个简化处理,将1和2两种情况当做一种. ...

  10. 基于VisualC++2010开发Windows7杀毒应用程序范例(2)---检测并遍历所有进程的线程信息...

    作为一个杀毒软件,必须扫描所有的进程的每一个线程,才能分析出病毒的行为! 下面我们演示下,基于Visual C++2010开发基于Windows7杀毒应用程序范例, 检测所有的进程线程信息 打开VS2 ...

最新文章

  1. shell排序_Java后端技术精选:希尔排序
  2. 一个小型数据库的核心组件
  3. 不固定图片宽高瀑布流_APP设计学习:瀑布流式的产品UI设计
  4. 为啥浏览器中的对象和w3c不一样??
  5. 【javascript】浮点数运算问题分析及解决方法
  6. vector的基础使用
  7. python 地理处理包:geopandas介绍
  8. android定义多个上下文菜单,Android编程实现为ListView创建上下文菜单(ContextMenu)的方法...
  9. pc机收集信息cpu\配置\网络信息
  10. 计算机中函数的括号怎么输,Excel函数中括号的使用
  11. java中 求余运算 % ,正负号问题
  12. java gdal开源库_基于GDAL库,读取.grd文件(以海洋地形数据为例)Java版
  13. 机器视觉:高动态范围图像
  14. python教程55--D-Tale使用介绍
  15. java怎么编写木马,实现简单木马免杀(示例代码)
  16. Flask项目: 蓝本
  17. windows中docker 安装和使用
  18. 并发编程之深入理解java线程
  19. 聚合支付介绍—简单明了一目了然
  20. 谢慧敏清晰版. 数学分析习题课讲义.下. 2004

热门文章

  1. leetcode 225. Implement Stack using Queuesk
  2. Deep Learning-Deep feedforward network
  3. 卷积神经网络的卷积操作
  4. 聚类算法 optics
  5. n倍角公式的行列式形式与证明
  6. Java对象创建过程
  7. 试验设计与matlab数据分析 下载,试验设计与MATLAB数据分析
  8. 怎样在html应用样式表,html – 如何仅将CSS样式应用于文本
  9. golang日志收集方案之ELK
  10. [MySQL]触发器