当前位置: 首页 > news >正文

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

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

相关文章:

  • /bin/rm: 参数列表过长"的解决办法
  • Compressive sensing for large images
  • MySQL分区表例子——List分区
  • iOS中常用的四种数据持久化方法简介
  • ASP.NET SignalR HubPipelineModule
  • DNS服务器中很重要的几个搭建配置---不看后悔哦
  • 一个老程序员的观察 国内外IT企业 震撼
  • Linux下用SCP无需输入密码传输文件
  • Head First 设计模式 (五) 单件模式(Singleton pattern) C++实现
  • 又一编辑神器-百度编辑器-Ueditor
  • SQL Server与MySQL之间的切换
  • window7如何提高到最高权限
  • [译]理解HEAD请求以及HTTP/204和HTTP/206响应
  • 第1讲:软件测试背景
  • 我要洗发液 洗衣粉 肥皂 威露士
  • 《用数据讲故事》作者Cole N. Knaflic:消除一切无效的图表
  • 【347天】每日项目总结系列085(2018.01.18)
  • 【Linux系统编程】快速查找errno错误码信息
  • 【跃迁之路】【519天】程序员高效学习方法论探索系列(实验阶段276-2018.07.09)...
  • angular学习第一篇-----环境搭建
  • Babel配置的不完全指南
  • CentOS6 编译安装 redis-3.2.3
  • E-HPC支持多队列管理和自动伸缩
  • java2019面试题北京
  • JavaScript设计模式系列一:工厂模式
  • Making An Indicator With Pure CSS
  • Node + FFmpeg 实现Canvas动画导出视频
  • php面试题 汇集2
  • php中curl和soap方式请求服务超时问题
  • tensorflow学习笔记3——MNIST应用篇
  • vue 配置sass、scss全局变量
  • Vue2.x学习三:事件处理生命周期钩子
  • 关于使用markdown的方法(引自CSDN教程)
  • 如何学习JavaEE,项目又该如何做?
  • 如何在GitHub上创建个人博客
  • 入手阿里云新服务器的部署NODE
  • 使用 Node.js 的 nodemailer 模块发送邮件(支持 QQ、163 等、支持附件)
  • 哈罗单车融资几十亿元,蚂蚁金服与春华资本加持 ...
  • 好程序员web前端教程分享CSS不同元素margin的计算 ...
  • 说说我为什么看好Spring Cloud Alibaba
  • # 透过事物看本质的能力怎么培养?
  • #13 yum、编译安装与sed命令的使用
  • (C语言)输入自定义个数的整数,打印出最大值和最小值
  • (ros//EnvironmentVariables)ros环境变量
  • (附源码)springboot优课在线教学系统 毕业设计 081251
  • (附源码)ssm高校运动会管理系统 毕业设计 020419
  • (入门自用)--C++--抽象类--多态原理--虚表--1020
  • (小白学Java)Java简介和基本配置
  • (已更新)关于Visual Studio 2019安装时VS installer无法下载文件,进度条为0,显示网络有问题的解决办法
  • (已解决)vue+element-ui实现个人中心,仿照原神
  • ***php进行支付宝开发中return_url和notify_url的区别分析
  • .NET / MSBuild 扩展编译时什么时候用 BeforeTargets / AfterTargets 什么时候用 DependsOnTargets?
  • .NET6实现破解Modbus poll点表配置文件
  • .Net接口调试与案例
  • .NET实现之(自动更新)