PointPro.cpp
上传用户:xayxjz
上传日期:2022-08-07
资源大小:2188k
文件大小:37k
源码类别:

图形图象

开发平台:

Visual C++

  1. // PointPro.cpp: implementation of the CPointPro class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. #include "stdafx.h"
  5. #include "CBIR.h"
  6. #include "PointPro.h"
  7. #ifdef _DEBUG
  8. #undef THIS_FILE
  9. static char THIS_FILE[]=__FILE__;
  10. #define new DEBUG_NEW
  11. #endif
  12. IMPLEMENT_DYNCREATE(CPointPro, CObject)
  13. //Diagnostics and dump member functions, overridden
  14. #ifdef _DEBUG
  15. void CPointPro::Dump(CDumpContext &dc) const
  16. {
  17. //call base class function first
  18. CObject::Dump(dc);
  19. }
  20. #endif
  21. #ifdef _DEBUG
  22. void CPointPro::AssertValid() const
  23. {
  24. //call inherited AssertValid first
  25. CObject::AssertValid();
  26. //Check CDibObject members...
  27. ASSERT(m_pDibObject != NULL); //Must exist
  28. }
  29. #endif
  30. /***********************************************************************
  31. *                                                                      *
  32. *                               点处理                                 *
  33. *                                                                      *
  34. ***********************************************************************/
  35. ////////////////////////////////////////////////////////////////////////
  36. //CPointPro()   
  37. //----------------------------------------------------------------------
  38. //基本功能:构造CPointPro类对象。由于此构造函数没有
  39. // CDibObject类,所以必须为其他所用到的CPointPro函
  40. // 数提供一个CDibObject构造器。
  41. //----------------------------------------------------------------------
  42. //参数说明:无
  43. //----------------------------------------------------------------------
  44. //返    回:无
  45. //----------------------------------------------------------------------
  46. ////////////////////////////////////////////////////////////////////////
  47. CPointPro::CPointPro()
  48. {
  49. }
  50. ////////////////////////////////////////////////////////////////////////
  51. //CPointPro(CDibObject *pDibObject)   
  52. //----------------------------------------------------------------------
  53. //基本功能:构造CPointPro类对象。由于此构造函数有一个
  54. // CDibObject类,所以无须为其他所用到的CPointPro函
  55. // 数提供一个CDibObject构造器
  56. //----------------------------------------------------------------------
  57. //参数说明:无
  58. //----------------------------------------------------------------------
  59. //返    回:无
  60. //----------------------------------------------------------------------
  61. ////////////////////////////////////////////////////////////////////////
  62. CPointPro::CPointPro( CDibObject *pDibObject )
  63. {
  64. m_pDibObject = pDibObject;
  65. }
  66. ////////////////////////////////////////////////////////////////////////
  67. //BOOL MakeGray256(BYTE mGrayType, CDibObject *pDibObject)   
  68. //----------------------------------------------------------------------
  69. //基本功能:本函数将传入的CDibObject对象中的图像从彩色转换为灰度图像。
  70. // 如果进行此调整之前没有指定一个CDibObject对象指针,则必须在
  71. // 调整时加以指定。
  72. //----------------------------------------------------------------------
  73. //参数说明:BYTE mGrayType  0:Y=0.3R+0.59G+0.11B 
  74. // 1: Y=R 
  75. // 2: Y=G
  76. // 3: Y=B
  77. // CDibObject *pDibObject, 默认为NULL。
  78. //----------------------------------------------------------------------
  79. //返    回:成功返回TRUE,失败返回FALSE。
  80. //----------------------------------------------------------------------
  81. ////////////////////////////////////////////////////////////////////////
  82. BOOL CPointPro::MakeGray256(BYTE mGrayType, 
  83. CDibObject *pDibObject )
  84. {
  85. //CDibObject对象指针
  86. if( pDibObject != NULL ) m_pDibObject = pDibObject;
  87. //若未指定 CDibObject 对象指针返回FALSE
  88. if( m_pDibObject == NULL ) return( FALSE );
  89. //低于8位的图像不进行处理
  90. if( m_pDibObject->GetNumBits() < 8 ) return( FALSE );
  91. //获取原图像字节宽度和转换后的8位256色灰度图像的字节宽度
  92. int nOldWidthBytes, nNewWidthBytes;
  93. char *pBuffer = (char *) m_pDibObject->GetDIBPointer( &nOldWidthBytes, 8, &nNewWidthBytes );
  94. if( pBuffer == NULL ) return( FALSE );
  95. //定义变量
  96. BITMAPINFOHEADER *pOldBIH, *pNewBIH;
  97. BITMAPFILEHEADER *pOldBFH, *pNewBFH;
  98. RGBQUAD *pOldRGBPalette, *pNewRGBPalette;
  99. unsigned char *pOldBits, *pNewBits, *pTemp, *pNewTemp;
  100. int nNumColors, nNumNewColors;
  101. //获取文件头指针
  102. pOldBFH = (BITMAPFILEHEADER *) pBuffer;
  103. //获取信息头指针
  104. pOldBIH = (BITMAPINFOHEADER *) &pBuffer[sizeof(BITMAPFILEHEADER)];
  105. //获取调色板指针
  106. pOldRGBPalette = (RGBQUAD *) &pBuffer[sizeof(BITMAPFILEHEADER)+
  107. sizeof(BITMAPINFOHEADER)];
  108. //原图像颜色数
  109. nNumColors = m_pDibObject->GetNumColors();
  110. //新图像颜色数
  111. nNumNewColors = 256;
  112. //获取原图像数据指针
  113. pOldBits = (unsigned char *) &pBuffer[sizeof(BITMAPFILEHEADER)
  114. +sizeof(BITMAPINFOHEADER)+nNumColors*sizeof(RGBQUAD)];
  115. //为新图像分配内存
  116. HGLOBAL hGlobal;
  117. //新图像总字节数
  118. DWORD dwSize;
  119. dwSize = sizeof( BITMAPFILEHEADER ) + sizeof( BITMAPINFOHEADER ) +
  120. 256 * sizeof( RGBQUAD ) + 
  121. m_pDibObject->GetHeight() * nNewWidthBytes;
  122. hGlobal = ::GlobalAlloc( GMEM_MOVEABLE | GMEM_ZEROINIT, dwSize );
  123. if( hGlobal == NULL )
  124. {
  125. ::GlobalUnlock( m_pDibObject->GetDib() );
  126. return( FALSE );
  127. }
  128. pBuffer = (char *) ::GlobalLock( hGlobal );
  129. if( pBuffer == NULL )
  130. {
  131. ::GlobalFree( hGlobal );
  132. ::GlobalUnlock( m_pDibObject->GetDib() );
  133. return( FALSE );
  134. }
  135. //获得新图像的文件头指针
  136. pNewBFH = (BITMAPFILEHEADER *) pBuffer;
  137. //获得新图像的信息头指针
  138. pNewBIH = (BITMAPINFOHEADER *) &pBuffer[sizeof(BITMAPFILEHEADER)];
  139. //获得新图像的调色板指针
  140. pNewRGBPalette = (RGBQUAD *) &pBuffer[sizeof(BITMAPFILEHEADER)
  141. +sizeof(BITMAPINFOHEADER)];
  142. //复制原图像文件头数据到新图像文件头
  143. *pNewBFH = *pOldBFH;
  144. //复制原图像信息头数据到新图像信息头
  145. *pNewBIH = *pOldBIH;
  146. //循环变量定义
  147. int i, j = 256, x, y;
  148. pNewBIH->biBitCount = 8;
  149. pNewBIH->biSizeImage = nNewWidthBytes * m_pDibObject->GetHeight();
  150. pNewBIH->biClrUsed = 256;
  151. pNewBFH->bfSize = sizeof( BITMAPFILEHEADER ) + 
  152. sizeof( BITMAPINFOHEADER ) + 
  153. 256 * sizeof( RGBQUAD ) + 
  154. pNewBIH->biSizeImage;
  155. pNewBFH->bfOffBits = sizeof( BITMAPFILEHEADER ) + 
  156. sizeof( BITMAPINFOHEADER ) + 
  157. nNumNewColors * sizeof( RGBQUAD );
  158. pNewBits = (unsigned char *) &pBuffer[sizeof(BITMAPFILEHEADER) +
  159. sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)];
  160. m_pDibObject->SetPaletteBytes( 256 * sizeof( RGBQUAD ));
  161. //创建256色灰度调色板
  162. for( i = 0; i < j; i++ )
  163. {
  164. pNewRGBPalette[i].rgbRed = i;
  165. pNewRGBPalette[i].rgbGreen = i;
  166. pNewRGBPalette[i].rgbBlue = i;
  167. }
  168. unsigned char *pLookup; //调色板查找表
  169. DWORD dwGray; //灰度级别
  170. switch( m_pDibObject->GetNumBits() )
  171. {
  172. case 8: //256色图像
  173. pLookup = new unsigned char [256];
  174. if( pLookup == NULL ) break;
  175. memset( pLookup, 0, 256 ); //调色板查找表清0(256项)
  176. switch( mGrayType)
  177. {
  178. case 0: //按亮度Y=0.3R+0.59G+0.11B将彩色图像转换为灰度图像
  179. for( i=0; i<256; i++ )
  180. {
  181. dwGray = ( (DWORD) pOldRGBPalette[i].rgbRed * 30 +
  182. (DWORD) pOldRGBPalette[i].rgbGreen * 59 +
  183. (DWORD) pOldRGBPalette[i].rgbBlue * 11 ) / 100;
  184. pLookup[i] = (unsigned char) dwGray;
  185. }
  186. break;
  187. case 1: //按亮度Y=R将彩色图像转换为灰度图像
  188. for( i=0; i<256; i++ )
  189. {
  190. dwGray =  (DWORD) pOldRGBPalette[i].rgbRed;
  191. pLookup[i] = (unsigned char) dwGray;
  192. }
  193. break;
  194. case 2: //按亮度Y=G将彩色图像转换为灰度图像
  195. for( i=0; i<256; i++ )
  196. {
  197. dwGray = (DWORD) pOldRGBPalette[i].rgbGreen;
  198. pLookup[i] = (unsigned char) dwGray;
  199. }
  200. break;
  201. case 3: //按亮度Y=B将彩色图像转换为灰度图像
  202. for( i=0; i<256; i++ )
  203. {
  204. dwGray =(DWORD) pOldRGBPalette[i].rgbBlue;
  205. pLookup[i] = (unsigned char) dwGray;
  206. }
  207. break;
  208. }
  209. for( y = 0; y < pOldBIH->biHeight; y++ )
  210. {
  211. pTemp = pOldBits; //位图数据起始指针
  212. pTemp += y * nOldWidthBytes; //位图数据下一行起始指针
  213. //转换成灰度索引
  214. for( x = 0; x < pOldBIH->biWidth; x++ ) pTemp[x] = pLookup[pTemp[x]];
  215. }
  216. delete [] pLookup; //释放pLookup查找表所占内存
  217. memcpy( pNewBits, pOldBits, nNewWidthBytes * m_pDibObject->GetHeight());
  218. break;
  219. case 16: //16位色真彩色图像
  220. unsigned char ucRed, ucGreen, ucBlue;
  221. for( y=0; y<pOldBIH->biHeight; y++ )
  222. {
  223. //位图数据起始指针
  224. pTemp = pOldBits;
  225. pNewTemp = pNewBits;
  226. //位图数据下一行起始指针
  227. pTemp += y * nOldWidthBytes;
  228. pNewTemp += y * nNewWidthBytes;
  229. switch( mGrayType )
  230. {
  231. case 0:
  232. for( x=0; x<pOldBIH->biWidth; x++ )
  233. {
  234. GETRGB555( ucRed, ucGreen, ucBlue, &pTemp[x*2] );
  235. //按亮度Y=0.3R+0.59G+0.11B将彩色图像转换为灰度图像
  236. dwGray = (ucRed * 30 + ucGreen * 59 +ucBlue * 11) / 100;
  237. //给新图像数据赋值
  238. pNewTemp[x] = (unsigned char)dwGray;
  239. }
  240. break;
  241. case 1:
  242. for( x=0; x<pOldBIH->biWidth; x++ )
  243. {
  244. GETRGB555( ucRed, ucGreen, ucBlue, &pTemp[x*2] );
  245. //按亮度Y=R将彩色图像转换为灰度图像
  246. dwGray = (ucRed * 30 + ucGreen * 59 +ucBlue * 11) / 100;
  247. //给新图像数据赋值
  248. pNewTemp[x] = (unsigned char)dwGray;
  249. }
  250. break;
  251. case 2:
  252. for( x=0; x<pOldBIH->biWidth; x++ )
  253. {
  254. GETRGB555( ucRed, ucGreen, ucBlue, &pTemp[x*2] );
  255. //按亮度Y=G将彩色图像转换为灰度图像
  256. dwGray = (ucRed * 30 + ucGreen * 59 +ucBlue * 11) / 100;
  257. //给新图像数据赋值
  258. pNewTemp[x] = (unsigned char)dwGray;
  259. }
  260. break;
  261. case 3:
  262. for( x=0; x<pOldBIH->biWidth; x++ )
  263. {
  264. GETRGB555( ucRed, ucGreen, ucBlue, &pTemp[x*2] );
  265. //按亮度Y=B将彩色图像转换为灰度图像
  266. dwGray = (ucRed * 30 + ucGreen * 59 +ucBlue * 11) / 100;
  267. //给新图像数据赋值
  268. pNewTemp[x] = (unsigned char)dwGray;
  269. }
  270. break;
  271. }
  272. }
  273. break;
  274. case 24: //24位真彩色图像
  275. for( y=0; y<pOldBIH->biHeight; y++ )
  276. {
  277. //位图数据起始指针
  278. pTemp = pOldBits;
  279. pNewTemp = pNewBits;
  280. //位图数据下一行起始指针
  281. pTemp += y * nOldWidthBytes;
  282. pNewTemp += y * nNewWidthBytes;
  283. switch( mGrayType )
  284. {
  285. case 0: //按亮度Y=0.3R+0.59G+0.11B将彩色图像转换为灰度图像
  286. for( x=0; x<pOldBIH->biWidth; x++ )
  287. {
  288. dwGray = ( (DWORD) pTemp[x*3+2] * 30 //红色
  289. +(DWORD) pTemp[x*3+1] * 59 //绿色
  290. +(DWORD) pTemp[x*3] * 11 //兰色
  291. ) / 100;
  292. //给新图像数据赋值
  293. pNewTemp[x] = (unsigned char)dwGray;
  294. }
  295. break;
  296. case 1: //按亮度Y=R将彩色图像转换为灰度图像
  297. for( x=0; x<pOldBIH->biWidth; x++ )
  298. {
  299. dwGray =  (DWORD) pTemp[x*3+2]; //红色
  300. //给新图像数据赋值
  301. pNewTemp[x] = (unsigned char)dwGray;
  302. }
  303. break;
  304. case 2: //按亮度Y=G将彩色图像转换为灰度图像
  305. for( x=0; x<pOldBIH->biWidth; x++ )
  306. {
  307. dwGray = (DWORD) pTemp[x*3+1] ; //绿色
  308. //给新图像数据赋值
  309. pNewTemp[x] = (unsigned char)dwGray;
  310. }
  311. break;
  312. case 3: //按亮度Y=B将彩色图像转换为灰度图像
  313. for( x=0; x<pOldBIH->biWidth; x++ )
  314. {
  315. dwGray =(DWORD) pTemp[x*3]; //兰色
  316. //给新图像数据赋值
  317. pNewTemp[x] = (unsigned char)dwGray;
  318. }
  319. break;
  320. }
  321. }
  322. break;
  323. case 32: //32位真彩色图像
  324. for( y=0; y<pOldBIH->biHeight; y++ )
  325. {
  326. //位图数据起始指针
  327. pTemp = pOldBits;
  328. pNewTemp = pNewBits;
  329. //位图数据下一行起始指针
  330. pTemp += y * nOldWidthBytes;
  331. pNewTemp += y * nNewWidthBytes;
  332. switch( mGrayType )
  333. {
  334. case 0:
  335. for( x=0; x<pOldBIH->biWidth; x++ )
  336. {
  337. //按亮度Y=0.3R+0.59G+0.11B将彩色图像转换为灰度图像
  338. dwGray = ( (DWORD) pTemp[x*4] * 30 //红色
  339. +(DWORD) pTemp[x*4+1] * 59 //绿色
  340. +(DWORD) pTemp[x*4+2] * 11 //兰色
  341. ) / 100;
  342. //给新图像数据赋值
  343. pNewTemp[x] = (unsigned char)dwGray;
  344. }
  345. break;
  346. case 1:
  347. for( x=0; x<pOldBIH->biWidth; x++ )
  348. {
  349. //按亮度Y=R将彩色图像转换为灰度图像
  350. dwGray =  (DWORD) pTemp[x*4];//红色
  351. //给新图像数据赋值
  352. pNewTemp[x] = (unsigned char)dwGray;
  353. }
  354. break;
  355. case 2:
  356. for( x=0; x<pOldBIH->biWidth; x++ )
  357. {
  358. //按亮度Y=G将彩色图像转换为灰度图像
  359. dwGray = (DWORD) pTemp[x*4+1] ; //绿色
  360. //给新图像数据赋值
  361. pNewTemp[x] = (unsigned char)dwGray;
  362. }
  363. break;
  364. case 3:
  365. for( x=0; x<pOldBIH->biWidth; x++ )
  366. {
  367. //按亮度Y=B将彩色图像转换为灰度图像
  368. dwGray =(DWORD) pTemp[x*4+2] ; //兰色
  369. //给新图像数据赋值
  370. pNewTemp[x] = (unsigned char)dwGray;
  371. }
  372. break;
  373. }
  374. }
  375. break;
  376. }
  377. ::GlobalUnlock( m_pDibObject->GetDib() );
  378. ::GlobalFree( m_pDibObject->GetDib() );
  379. ::GlobalUnlock( hGlobal );
  380. m_pDibObject->SetDib( hGlobal );
  381. m_pDibObject->ProcessImageHeader();
  382. m_pDibObject->m_nLastError = IMAGELIB_SUCCESS;
  383. return( TRUE );
  384. }
  385. void CPointPro::SetDibObjectClass( CDibObject *pDibObject )
  386. {
  387.    m_pDibObject = pDibObject;
  388. }
  389. ////////////////////////////////////////////////////////////////////////
  390. //int *CreateHistogram()   
  391. //----------------------------------------------------------------------
  392. //基本功能:本函数创建传入的CDibObject对象中图像的直方图。如果进行此调
  393. // 整之前没有指定一个CDibObject对象指针,则必须在调整时加以指
  394. // 定。任何未传入的坐标值或默认的-1坐标值都将被置为图像的最大值
  395. // 或最大植。变量nX1和nY1将被置为0,nX2将被置为图像宽度减1,nY2
  396. // 将被置为图像高度减1。想要在整个图像上进行操作时,最好的方法
  397. // 是不传入nX1、nY1、nX2和nY2值。这样它们会被默认为整个图像。
  398. //----------------------------------------------------------------------
  399. //参数说明:int nX1 默认为-1
  400. // int nY1 默认为-1
  401. // int nX2 默认为-1
  402. // int nY2 默认为-1
  403. // unsigned char *pData 图像位图数据指针
  404. // RGBQUAD *pPalette 图像调色板指针
  405. // int nWidthBytes 图像字节宽度
  406. // CDibObject *pDibObject 默认为NULL。
  407. //----------------------------------------------------------------------
  408. //返    回:直方图数组指针*pBuffer其中:
  409. // pBuffer[] 存储亮度直方图数据
  410. // pBuffer[256] 存储红色直方图数据
  411. // pBuffer[512] 存储绿色直方图数据
  412. // pBuffer[768] 存储蓝直方图数据
  413. //----------------------------------------------------------------------
  414. ////////////////////////////////////////////////////////////////////////
  415. int * CPointPro::CreateHistogram( int nX1, int nY1, int nX2, int nY2, 
  416.    unsigned char *pData, RGBQUAD *pPalette, 
  417.    int nWidthBytes, CDibObject *pDibObject )
  418. {
  419. //图像指针为空,无法操作返回
  420. if( pDibObject != NULL ) m_pDibObject = pDibObject;
  421. if( m_pDibObject == NULL ) return( FALSE );
  422. //分配直方图数据缓存区(数组)
  423. int *pBuffer = new int [256 * 4];
  424. //分配直方图数据缓存区失败
  425. if( pBuffer == NULL ) return( NULL );
  426. //直方图数据缓存区清零
  427. memset( pBuffer, 0, ( 256 * 4) * sizeof( int ) );
  428. //变量定义
  429. DWORD dwGray;
  430. int x, y;
  431. unsigned char *pTemp, ucRed, ucGreen, ucBlue;
  432. //图像的高度
  433. int nHeight = m_pDibObject->GetHeight();
  434. switch( m_pDibObject->GetNumBits() )
  435. {
  436. case 1: //每像素位数为1,不处理
  437. break;
  438. case 4: //每像素位数为4,不处理
  439. break;
  440. case 8: //每像素位数为8
  441. for( y = nY1; y <= nY2; y++ )
  442. {
  443. //数据指针定位到图像数据起始位置
  444. pTemp = pData;
  445. //数据指针定位到图像数据每行的起始零位置
  446. pTemp += ( ( nHeight - 1 - y ) * nWidthBytes );
  447. //数据指针定位到图像数据每行的起始nX1位置
  448. pTemp += nX1;
  449. for( x = nX1; x <= nX2; x++ )
  450. {
  451. //pTemp[x]为当前像素值,它为调色板项的索引值,
  452. //以此为索引,取出调色板项的相应红绿蓝分量值。
  453. ucRed   = pPalette[pTemp[x]].rgbRed;
  454. ucGreen = pPalette[pTemp[x]].rgbGreen;
  455. ucBlue  = pPalette[pTemp[x]].rgbBlue;
  456. //按关系L=0.3R+0.59G+0.11B,得到亮度值
  457. dwGray  = ( (DWORD) ucRed * 30 +
  458.         (DWORD) ucGreen * 59 +
  459.         (DWORD) ucBlue * 11 ) / 100;
  460. dwGray &= 0x000000ff;
  461. //亮度直方图数据
  462. pBuffer[dwGray]++;
  463. //红色直方图数据
  464. pBuffer[256 + ucRed]++;
  465. //绿色直方图数据
  466. pBuffer[512 + ucGreen]++;
  467. //蓝色直方图数据
  468. pBuffer[768 + ucBlue]++;
  469. }
  470. }
  471. break;
  472. case 16: //每像素位数为16
  473. for( y = nY1; y <= nY2; y++ )
  474. {
  475. //数据指针定位到图像数据起始位置
  476. pTemp = pData;
  477. //数据指针定位到图像数据每行的起始零位置
  478. pTemp += ( ( nHeight - 1 - y ) * nWidthBytes );
  479. //数据指针定位到图像数据每行的起始nX1位置
  480. pTemp += ( nX1 * 2 );
  481. for( x = nX1; x <= nX2; x++ )
  482. {
  483. //获取三原色分量
  484. GETRGB555( ucRed, ucGreen, ucBlue, pTemp );
  485. //按关系L=0.3R+0.59G+0.11B,得到亮度值
  486. dwGray = ( (DWORD) ucRed * 30 +
  487.        (DWORD) ucGreen * 59 +
  488.        (DWORD) ucBlue * 11 ) / 100;
  489. dwGray &= 0x000000ff;
  490. //亮度直方图数据
  491. pBuffer[dwGray]++;
  492. //红色直方图数据
  493. pBuffer[256 + ucRed]++;
  494. //绿色直方图数据
  495. pBuffer[512 + ucGreen]++;
  496. //蓝色直方图数据
  497. pBuffer[768 + ucBlue]++;
  498. //数据指针加2
  499. pTemp += 2;
  500. }
  501. }
  502. break;
  503. case 24: //每像素位数为24
  504. for( y = nY1; y < nY2; y++ )
  505. {
  506. //数据指针定位到图像数据起始位置
  507. pTemp = pData;
  508. //数据指针定位到图像数据每行的起始零位置
  509. pTemp += ( ( nHeight - 1 - y ) * nWidthBytes );
  510. //数据指针定位到图像数据每行的起始nX1位置
  511. pTemp += ( nX1 * 3 );
  512. for( x=nX1; x<=nX2; x++ )
  513. {
  514. //获取像素颜色的三原色。
  515. ucRed   = pTemp[x * 3 + 2];
  516. ucGreen = pTemp[x * 3 + 1];
  517. ucBlue  = pTemp[x * 3];
  518. //按关系L=0.3R+0.59G+0.11B,得到亮度值
  519. dwGray  = ( (DWORD) ucRed * 30 +
  520.         (DWORD) ucGreen * 59 +
  521.         (DWORD) ucBlue * 11 ) / 100;
  522. dwGray &= 0x000000ff;
  523. //亮度直方图数据
  524. pBuffer[dwGray]++;
  525. //红色直方图数据
  526. pBuffer[256 + ucRed]++;
  527. //绿色直方图数据
  528. pBuffer[512 + ucGreen]++;
  529. //蓝色直方图数据
  530. pBuffer[768 + ucBlue]++;
  531. //数据指针加3
  532. pTemp += 3;
  533. }
  534. }
  535. break;
  536. case 32: //每像素位数为24
  537. for( y = nY1; y <= nY2; y++ )
  538. {
  539. //数据指针定位到图像数据起始位置
  540. pTemp = pData;
  541. //数据指针定位到图像数据每行的起始零位置
  542. pTemp += ( ( nHeight - 1 - y ) * nWidthBytes );
  543. //数据指针定位到图像数据每行的起始nX1位置
  544. pTemp += ( nX1 * 4 );
  545. for( x = nX1; x <= nX2; x++ )
  546. {
  547. //获取像素颜色的三原色。
  548. GETRGB888( ucRed, ucGreen, ucBlue, pTemp );
  549. //按关系L=0.3R+0.59G+0.11B,得到亮度值
  550. dwGray = ( (DWORD) ucRed * 30 +
  551.        (DWORD) ucGreen * 59 +
  552.        (DWORD) ucBlue * 11 ) / 100;
  553. dwGray &= 0x000000ff;
  554. //亮度直方图数据
  555. pBuffer[dwGray]++;
  556. //红色直方图数据
  557. pBuffer[256 + ucRed]++;
  558. //绿色直方图数据
  559. pBuffer[512 + ucGreen]++;
  560. //蓝色直方图数据
  561. pBuffer[768 + ucBlue]++;
  562. pTemp += 4;
  563. }
  564. }
  565. break;
  566. }
  567. return( pBuffer );
  568. }
  569. ////////////////////////////////////////////////////////////////////////
  570. //BOOL IsGray256(CDibObject *pDibObject)
  571. //----------------------------------------------------------------------
  572. //基本功能:本函数判断传入的CDibObject对象中的图像是否为256级灰度图像。
  573. //----------------------------------------------------------------------
  574. //参数说明:CDibObject *pDibObject, 默认为NULL
  575. //----------------------------------------------------------------------
  576. //返回:BOOL:成功返回TRUE,失败返回FALSE。
  577. //----------------------------------------------------------------------
  578. ////////////////////////////////////////////////////////////////////////
  579. BOOL CPointPro::IsGray256( CDibObject *pDibObject )
  580. {
  581. //使用传入的CDibObject对象
  582. if( pDibObject != NULL ) m_pDibObject = pDibObject;
  583. //无CDibObject对象, 返回FALSE
  584. if( m_pDibObject == NULL ) return( FALSE );
  585. //不是8位图像,必不是256级灰度图像,不处理返回FALSE
  586. if( m_pDibObject->GetNumBits() != 8 ) return( FALSE );
  587. //定义变量
  588. unsigned char *pBuffer;
  589. RGBQUAD *pPalette;
  590. int nWidthBytes, i;
  591. //pBuffer: 获得位图数据指针
  592. pBuffer = (unsigned char *) m_pDibObject->GetDIBPointer( &nWidthBytes, 
  593. m_pDibObject->GetNumBits() );
  594. if( pBuffer == NULL ) return( FALSE );
  595. //pPalette:获得调色板数据地址
  596. pPalette = (RGBQUAD *) &pBuffer[sizeof(BITMAPFILEHEADER)+
  597. sizeof(BITMAPINFOHEADER)];
  598. //检查是否为256色灰度调色板
  599. for( i=0; i<256; i++ )
  600. {
  601. if( pPalette[i].rgbRed != pPalette[i].rgbGreen 
  602. || pPalette[i].rgbRed != pPalette[i].rgbBlue
  603. || pPalette[i].rgbGreen != pPalette[i].rgbBlue )
  604. return( FALSE);
  605. }
  606. ::GlobalUnlock( m_pDibObject->GetDib() );
  607. return( TRUE );
  608. }
  609. ////////////////////////////////////////////////////////////////////////
  610. //BOOL ReplaceColorPal()
  611. //----------------------------------------------------------------------
  612. //基本功能:本函数对传入的CDibObject对象中的图像用指定的伪彩色编码表来
  613. // 替换图像的调试板。
  614. //----------------------------------------------------------------------
  615. //参数说明:CDibObject *pDibObject, 默认为NULL
  616. // BYTE * bpColorsTable - 伪彩色编码表
  617. //----------------------------------------------------------------------
  618. //返回:BOOL:成功返回TRUE,失败返回FALSE。
  619. //----------------------------------------------------------------------
  620. ////////////////////////////////////////////////////////////////////////
  621. BOOL CPointPro::ReplaceColorPal(CDibObject *pDibObject, 
  622.    BYTE *bpColorsTable)
  623. {
  624. //CDibObject对象指针
  625. if( pDibObject != NULL ) m_pDibObject = pDibObject;
  626. //若未指定 CDibObject 对象指针返回FALSE
  627. if( m_pDibObject == NULL ) return( FALSE );
  628. //定义变量
  629. unsigned char *pBuffer;
  630. BITMAPINFOHEADER *pBIH;
  631. RGBQUAD *pPalette;
  632. int nWidthBytes, nNumColors;
  633. //pBuffer: 获得位图数据指针
  634. pBuffer = (unsigned char *) m_pDibObject->GetDIBPointer( &nWidthBytes, 
  635. m_pDibObject->GetNumBits() );
  636. if( pBuffer == NULL ) return( FALSE );
  637. //pBIH:获得位图信息头地址
  638. pBIH = (BITMAPINFOHEADER *) &pBuffer[sizeof(BITMAPFILEHEADER)];
  639. //nNumColors:获得调色板中的颜色数。图像为16位色或更高时为0
  640. nNumColors = m_pDibObject->GetNumColors();
  641. //pPalette:获得调色板数据地址
  642. pPalette = (RGBQUAD *) &pBuffer[sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)];
  643. //pBits:获得位图数据地址
  644. // 读取伪彩色编码,更新DIB调色板
  645. for(int i=0; i<256; i++ )
  646. {
  647. // 更新DIB调色板红色分量
  648. pPalette[i].rgbRed = bpColorsTable[i * 4];
  649. // 更新DIB调色板绿色分量
  650. pPalette[i].rgbGreen = bpColorsTable[i * 4 + 1];
  651. // 更新DIB调色板蓝色分量
  652. pPalette[i].rgbBlue = bpColorsTable[i * 4 + 2];
  653. // 更新DIB调色板保留位
  654. pPalette[i].rgbReserved = 0;
  655. }
  656. ::GlobalUnlock( m_pDibObject->GetDib() );
  657. return(TRUE);
  658. }
  659. ////////////////////////////////////////////////////////////////////////
  660. //int *GetHistogram()   
  661. //----------------------------------------------------------------------
  662. //基本功能:本函数获得传入的CDibObject对象中图像的直方图。如果进行此调
  663. // 整之前没有指定一个CDibObject对象指针,则必须在调整时加以指
  664. // 定。任何未传入的坐标值或默认的-1坐标值都将被置为图像的最大值
  665. // 或最大植。变量nX1和nY1将被置为0,nX2将被置为图像宽度减1,nY2
  666. // 将被置为图像高度减1。想要在整个图像上进行操作时,最好的方法
  667. // 是不传入nX1、nY1、nX2和nY2值。这样它们会被默认为整个图像。
  668. //----------------------------------------------------------------------
  669. //参数说明:int nX1, 默认为-1
  670. // int nY1, 默认为-1
  671. // int nX2, 默认为-1
  672. // int nY2, 默认为-1
  673. // CDibObject *pDibObject, 默认为NULL。
  674. //----------------------------------------------------------------------
  675. //返    回:直方图数组指针*pBuffer其中:
  676. // nHistogramBuffer[] 存储亮度直方图数据
  677. // nHistogramBuffer[256] 存储红色直方图数据
  678. // nHistogramBuffer[512] 存储绿色直方图数据
  679. // nHistogramBuffer[768] 存储蓝直方图数据
  680. //----------------------------------------------------------------------
  681. ////////////////////////////////////////////////////////////////////////
  682. int * CPointPro::GetHistogram( int nX1, 
  683. int nY1,
  684. int nX2,
  685. int nY2,
  686. CDibObject *pDibObject)
  687. {
  688. //使用传入的CDibObject对象
  689. if( pDibObject != NULL ) m_pDibObject = pDibObject;
  690. //无CDibObject对象, 返回FALSE
  691. if( m_pDibObject == NULL ) return( FALSE );
  692. //坐标规整化
  693. m_pDibObject->NormalizeCoordinates( &nX1, &nY1, &nX2, &nY2 );
  694. //定义变量
  695. unsigned char *pBuffer, *pBits;
  696. RGBQUAD *pPalette;
  697. int nWidthBytes, nNumColors;
  698. //获得图像指针
  699. pBuffer = (unsigned char *) m_pDibObject->GetDIBPointer( &nWidthBytes, m_pDibObject->GetNumBits() );
  700. if( pBuffer == NULL ) return( NULL );
  701. //获得颜色数
  702. nNumColors = m_pDibObject->GetNumColors();
  703. //获得调色板指针
  704. pPalette = (RGBQUAD *) &pBuffer[sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)];
  705. //获得位图数据指针
  706. pBits = (unsigned char *) &pBuffer[sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+nNumColors*sizeof(RGBQUAD)];
  707. //创建直方图数据
  708. int *nHistogramBuffer = CreateHistogram( nX1, nY1, nX2, nY2, pBits, pPalette, nWidthBytes );
  709. ::GlobalUnlock( m_pDibObject->GetDib() );
  710. return( nHistogramBuffer );
  711. }
  712. ////////////////////////////////////////////////////////////////////////
  713. //BOOL SplitChannels()   
  714. //----------------------------------------------------------------------
  715. //基本功能:本函数将传入的CDibObject对象中的图像分离成由红、绿、蓝分量
  716. // 构成的256色灰度图像。
  717. //----------------------------------------------------------------------
  718. //参数说明:CDibObject *pRed 指向红色通道的图像指针
  719. // CDibObject *pGreen 指向绿色通道的图像指针
  720. // CDibObject *pBlue 指向蓝色通道的图像指针
  721. //----------------------------------------------------------------------
  722. //返    回:成功返回TRUE,失败返回FALSE。
  723. //----------------------------------------------------------------------
  724. ////////////////////////////////////////////////////////////////////////
  725. BOOL CPointPro::SplitChannels(CDibObject *pRed, 
  726.   CDibObject *pGreen, 
  727.   CDibObject *pBlue)
  728. {
  729. //没有传入相应指针无法完成操作
  730. if(m_pDibObject == NULL)
  731. {
  732. AfxMessageBox("没有传入原始图像,无法完成操作!");
  733. return FALSE;
  734. }
  735. if(pRed == NULL)
  736. {
  737. AfxMessageBox("没有传入红色通道指针,无法完成操作!");
  738. return FALSE;
  739. }
  740. if(pGreen == NULL)
  741. {
  742. AfxMessageBox("没有传入绿色通道指针,无法完成操作!");
  743. return FALSE;
  744. }
  745. if(pBlue == NULL)
  746. {
  747. AfxMessageBox("没有传入蓝色通道指针,无法完成操作!");
  748. return FALSE;
  749. }
  750. //已是256色灰度图像不用再转换
  751. if(IsGray256())
  752. {
  753. AfxMessageBox("已是256色灰度图像,不能进行通道分离!");
  754. return FALSE;
  755. }
  756. //红色通道
  757. MakeGray256(1, pRed);
  758. //绿色通道
  759. MakeGray256(2, pGreen);
  760. //蓝色通道
  761. MakeGray256(3, pBlue);
  762. return TRUE;
  763. }
  764. ////////////////////////////////////////////////////////////////////////
  765. //BOOL GetMixedChannel()   
  766. //----------------------------------------------------------------------
  767. //基本功能:本函数获得传入的CDibObject对象中的图像中的混合分量通道。
  768. //----------------------------------------------------------------------
  769. //参数说明:CDibObject *pMixed 指向混合通道的图像指针
  770. //----------------------------------------------------------------------
  771. //返    回:成功返回TRUE,失败返回FALSE。
  772. //----------------------------------------------------------------------
  773. ////////////////////////////////////////////////////////////////////////
  774. BOOL CPointPro::GetMixedChannel(CDibObject *pMixed)
  775. {
  776. //没有传入相应指针无法完成操作
  777. if(m_pDibObject == NULL)
  778. {
  779. AfxMessageBox("没有传入原始图像,无法完成操作!");
  780. return FALSE;
  781. }
  782. if(pMixed == NULL)
  783. {
  784. AfxMessageBox("没有传入通道指针,无法完成操作!");
  785. return FALSE;
  786. }
  787. //已是256色灰度图像不用再转换
  788. if(IsGray256())
  789. {
  790. AfxMessageBox("已是256色灰度图像,不能进行通道分离!");
  791. return FALSE;
  792. }
  793. MakeGray256(0, pMixed);
  794. return TRUE;
  795. }
  796. ////////////////////////////////////////////////////////////////////////
  797. //BOOL GetRedChannel()   
  798. //----------------------------------------------------------------------
  799. //基本功能:本函数获得传入的CDibObject对象中的图像中的红色分量通道。
  800. //----------------------------------------------------------------------
  801. //参数说明:CDibObject *pRed 指向红色通道的图像指针
  802. //----------------------------------------------------------------------
  803. //返    回:成功返回TRUE,失败返回FALSE。
  804. //----------------------------------------------------------------------
  805. ////////////////////////////////////////////////////////////////////////
  806. BOOL CPointPro::GetRedChannel(CDibObject *pRed)
  807. {
  808. //没有传入相应指针无法完成操作
  809. if(m_pDibObject == NULL)
  810. {
  811. AfxMessageBox("没有传入原始图像,无法完成操作!");
  812. return FALSE;
  813. }
  814. if(pRed == NULL)
  815. {
  816. AfxMessageBox("没有传入红色通道指针,无法完成操作!");
  817. return FALSE;
  818. }
  819. //已是256色灰度图像不用再转换
  820. if(IsGray256())
  821. {
  822. AfxMessageBox("已是256色灰度图像,不能进行通道分离!");
  823. return FALSE;
  824. }
  825. //红色通道
  826. MakeGray256(1, pRed);
  827. return TRUE;
  828. }
  829. ////////////////////////////////////////////////////////////////////////
  830. //BOOL GetGreenChannel()   
  831. //----------------------------------------------------------------------
  832. //基本功能:本函数获得传入的CDibObject对象中的图像中的绿色分量通道。
  833. //----------------------------------------------------------------------
  834. //参数说明:CDibObject *pGreen 指向混合通道的图像指针
  835. //----------------------------------------------------------------------
  836. //返    回:成功返回TRUE,失败返回FALSE。
  837. //----------------------------------------------------------------------
  838. ////////////////////////////////////////////////////////////////////////
  839. BOOL CPointPro::GetGreenChannel(CDibObject *pGreen)
  840. {
  841. //没有传入相应指针无法完成操作
  842. if(m_pDibObject == NULL)
  843. {
  844. AfxMessageBox("没有传入原始图像,无法完成操作!");
  845. return FALSE;
  846. }
  847. if(pGreen == NULL)
  848. {
  849. AfxMessageBox("没有传入通道指针,无法完成操作!");
  850. return FALSE;
  851. }
  852. //已是256色灰度图像不用再转换
  853. if(IsGray256())
  854. {
  855. AfxMessageBox("已是256色灰度图像,不能进行通道分离!");
  856. return FALSE;
  857. }
  858. MakeGray256(2, pGreen);
  859. return TRUE;
  860. }
  861. ////////////////////////////////////////////////////////////////////////
  862. //BOOL GetBlueChannel()   
  863. //----------------------------------------------------------------------
  864. //基本功能:本函数获得传入的CDibObject对象中的图像中的蓝色分量通道。
  865. //----------------------------------------------------------------------
  866. //参数说明:CDibObject *pBlue 指向蓝色通道的图像指针
  867. //----------------------------------------------------------------------
  868. //返    回:成功返回TRUE,失败返回FALSE。
  869. //----------------------------------------------------------------------
  870. ////////////////////////////////////////////////////////////////////////
  871. BOOL CPointPro::GetBlueChannel(CDibObject *pBlue)
  872. {
  873. //没有传入相应指针无法完成操作
  874. if(m_pDibObject == NULL)
  875. {
  876. AfxMessageBox("没有传入原始图像,无法完成操作!");
  877. return FALSE;
  878. }
  879. if(pBlue == NULL)
  880. {
  881. AfxMessageBox("没有传入通道指针,无法完成操作!");
  882. return FALSE;
  883. }
  884. //已是256色灰度图像不用再转换
  885. if(IsGray256())
  886. {
  887. AfxMessageBox("已是256色灰度图像,不能进行通道分离!");
  888. return FALSE;
  889. }
  890. MakeGray256(3, pBlue);
  891. return TRUE;
  892. }
  893. ////////////////////////////////////////////////////////////////////////
  894. //BOOL CombineChannels()   
  895. //----------------------------------------------------------------------
  896. //基本功能:本函数将传入的由红、绿、蓝分量构成的256色灰度图像合成为采色图
  897. // 像。
  898. //----------------------------------------------------------------------
  899. //参数说明:CDibObject *pRed 指向红色通道的图像指针
  900. // CDibObject *pGreen 指向绿色通道的图像指针
  901. // CDibObject *pBlue 指向蓝色通道的图像指针
  902. //----------------------------------------------------------------------
  903. //返    回:成功返回TRUE,失败返回FALSE。
  904. //----------------------------------------------------------------------
  905. ////////////////////////////////////////////////////////////////////////
  906. BOOL CPointPro::CombineChannels(CDibObject *pRed, 
  907. CDibObject *pGreen, 
  908. CDibObject *pBlue)
  909. {
  910. //没有传入相应指针无法完成操作
  911. if(m_pDibObject == NULL)
  912. {
  913. AfxMessageBox("没有传入创建新图像,无法完成操作!");
  914. return FALSE;
  915. }
  916. if(pRed == NULL)
  917. {
  918. AfxMessageBox("没有传入红色通道指针,无法完成操作!");
  919. return FALSE;
  920. }
  921. if(pGreen == NULL)
  922. {
  923. AfxMessageBox("没有传入绿色通道指针,无法完成操作!");
  924. return FALSE;
  925. }
  926. if(pBlue == NULL)
  927. {
  928. AfxMessageBox("没有传入蓝色通道指针,无法完成操作!");
  929. return FALSE;
  930. }
  931. //传入的图像不符合需要的格式,无法完成操作
  932. if(pRed->GetNumBits() != 8)
  933. {
  934. AfxMessageBox("传入的红色通道不是8位图像,无法完成操作!");
  935. return FALSE;
  936. }
  937. if(pGreen->GetNumBits() != 8)
  938. {
  939. AfxMessageBox("传入的绿色通道不是8位图像,无法完成操作!");
  940. return FALSE;
  941. }
  942. if(pBlue->GetNumBits() != 8)
  943. {
  944. AfxMessageBox("传入的蓝色通道不是8位图像,无法完成操作!");
  945. return FALSE;
  946. }
  947. //创建的图像不是24位图像将其转换为24位图像
  948. if(m_pDibObject->GetNumBits() != 24)
  949. {
  950. m_pDibObject->ChangeFormat(24);
  951. }
  952. //获得各个图像的大小
  953. int nCombineWidth, nRedWidth, nGreenWidth, nBlueWidth;
  954. int nCombineHeight, nRedHeight, nGreenHeight, nBlueHeight;
  955. //合并后图像的大小
  956. nCombineWidth = m_pDibObject->GetWidth();
  957. nCombineHeight = m_pDibObject->GetHeight();
  958. //红色通道图像大小
  959. nRedWidth = pRed->GetWidth();
  960. nRedHeight = pRed->GetHeight();
  961. //绿色通道图像大小
  962. nGreenWidth = pGreen->GetWidth();
  963. nGreenHeight = pGreen->GetHeight();
  964. //蓝色通道图像大小
  965. nBlueWidth = pBlue->GetWidth();
  966. nBlueHeight = pBlue->GetHeight();
  967. CRect rectCombine(0, 0, nCombineWidth, nCombineHeight);
  968. CRect rectRed(0, 0, nRedWidth, nRedHeight);
  969. CRect rectGreen(0, 0, nGreenWidth, nGreenHeight);
  970. CRect rectBlue(0, 0, nBlueWidth, nBlueHeight);
  971. //所有图像的大小应一致
  972. if (rectCombine != rectRed 
  973. || rectRed != rectGreen 
  974. || rectGreen != rectBlue 
  975. || rectBlue != rectCombine)
  976. {
  977. AfxMessageBox("各个通道大小不一致,无法完成操作!");
  978. return FALSE;
  979. }
  980. //获取各个通道原图像字节宽度
  981. int nCombineWidthBytes, nRedWidthBytes, nGreenWidthBytes, nBlueWidthBytes;
  982. //合并的图像的字节宽度
  983. char *pCombineBuffer = (char *) m_pDibObject->GetDIBPointer(&nCombineWidthBytes);
  984. if( pCombineBuffer == NULL ) return( FALSE );
  985. //红色通道的图像的字节宽度
  986. char *pRedBuffer = (char *) pRed->GetDIBPointer(&nRedWidthBytes);
  987. if( pRedBuffer == NULL ) return( FALSE );
  988. //绿色通道的图像的字节宽度
  989. char *pGreenBuffer = (char *) pGreen->GetDIBPointer(&nGreenWidthBytes);
  990. if( pGreenBuffer == NULL ) return( FALSE );
  991. //蓝色通道的图像的字节宽度
  992. char *pBlueBuffer = (char *) pBlue->GetDIBPointer(&nBlueWidthBytes);
  993. if( pBlueBuffer == NULL ) return( FALSE );
  994. //定义变量
  995. BITMAPINFOHEADER *pCombineBIH, *pRedBIH, *pGreenBIH, *pBlueBIH;
  996. BITMAPFILEHEADER *pCombineBFH, *pRedBFH, *pGreenBFH, *pBlueBFH;
  997. RGBQUAD *pCombineRGBPalette, *pRedRGBPalette, *pGreenRGBPalette, *pBlueRGBPalette;
  998. unsigned char *pCombineBits, *pRedBits, *pGreenBits, *pBlueBits;
  999. unsigned char *pCombineTemp, *pRedTemp, *pGreenTemp, *pBlueTemp;
  1000. int nCombineNumColors, nRedNumColors, nGreenNumColors, nBlueNumColors;
  1001. //合并后的图像信息
  1002. //获取文件头指针
  1003. pCombineBFH = (BITMAPFILEHEADER *) pCombineBuffer;
  1004. //获取信息头指针
  1005. pCombineBIH = (BITMAPINFOHEADER *) &pCombineBuffer[sizeof(BITMAPFILEHEADER)];
  1006. //获取调色板指针
  1007. pCombineRGBPalette = (RGBQUAD *) &pCombineBuffer[sizeof(BITMAPFILEHEADER)+
  1008. sizeof(BITMAPINFOHEADER)];
  1009. //图像颜色数
  1010. nCombineNumColors = m_pDibObject->GetNumColors();
  1011. //获取原图像数据指针
  1012. pCombineBits = (unsigned char *) &pCombineBuffer[sizeof(BITMAPFILEHEADER)
  1013. +sizeof(BITMAPINFOHEADER)+nCombineNumColors*sizeof(RGBQUAD)];
  1014. //红色通道的图像信息
  1015. //获取文件头指针
  1016. pRedBFH = (BITMAPFILEHEADER *) pRedBuffer;
  1017. //获取信息头指针
  1018. pRedBIH = (BITMAPINFOHEADER *) &pRedBuffer[sizeof(BITMAPFILEHEADER)];
  1019. //获取调色板指针
  1020. pRedRGBPalette = (RGBQUAD *) &pRedBuffer[sizeof(BITMAPFILEHEADER)+
  1021. sizeof(BITMAPINFOHEADER)];
  1022. //图像颜色数
  1023. nRedNumColors = pRed->GetNumColors();
  1024. //获取原图像数据指针
  1025. pRedBits = (unsigned char *) &pRedBuffer[sizeof(BITMAPFILEHEADER)
  1026. +sizeof(BITMAPINFOHEADER)+nRedNumColors*sizeof(RGBQUAD)];
  1027. //绿色通道的图像信息
  1028. //获取文件头指针
  1029. pGreenBFH = (BITMAPFILEHEADER *) pGreenBuffer;
  1030. //获取信息头指针
  1031. pGreenBIH = (BITMAPINFOHEADER *) &pGreenBuffer[sizeof(BITMAPFILEHEADER)];
  1032. //获取调色板指针
  1033. pGreenRGBPalette = (RGBQUAD *) &pGreenBuffer[sizeof(BITMAPFILEHEADER)+
  1034. sizeof(BITMAPINFOHEADER)];
  1035. //图像颜色数
  1036. nGreenNumColors = pGreen->GetNumColors();
  1037. //获取原图像数据指针
  1038. pGreenBits = (unsigned char *) &pGreenBuffer[sizeof(BITMAPFILEHEADER)
  1039. +sizeof(BITMAPINFOHEADER)+nGreenNumColors*sizeof(RGBQUAD)];
  1040. //蓝色通道的图像信息
  1041. //获取文件头指针
  1042. pBlueBFH = (BITMAPFILEHEADER *) pBlueBuffer;
  1043. //获取信息头指针
  1044. pBlueBIH = (BITMAPINFOHEADER *) &pBlueBuffer[sizeof(BITMAPFILEHEADER)];
  1045. //获取调色板指针
  1046. pBlueRGBPalette = (RGBQUAD *) &pBlueBuffer[sizeof(BITMAPFILEHEADER)+
  1047. sizeof(BITMAPINFOHEADER)];
  1048. //图像颜色数
  1049. nBlueNumColors = pBlue->GetNumColors();
  1050. //获取原图像数据指针
  1051. pBlueBits = (unsigned char *) &pBlueBuffer[sizeof(BITMAPFILEHEADER)
  1052. +sizeof(BITMAPINFOHEADER)+nBlueNumColors*sizeof(RGBQUAD)];
  1053. //循环变量定义
  1054. int x, y;
  1055. //行位置
  1056. for(y = 0; y < nCombineHeight; y++ )
  1057. {
  1058. //合并后的图像数据指针定位到起始位置
  1059. pCombineTemp = pCombineBits;
  1060. //合并后的图像数据指针定位到图像数据每行的起始零位置
  1061. pCombineTemp += y * nCombineWidthBytes;
  1062. //红色通道图像数据指针定位到起始位置
  1063. pRedTemp = pRedBits;
  1064. //红色通道图像数据指针定位到图像数据每行的起始零位置
  1065. pRedTemp += y * nRedWidthBytes;
  1066. //绿色通道图像数据指针定位到起始位置
  1067. pGreenTemp = pGreenBits;
  1068. //绿色通道图像数据指针定位到图像数据每行的起始零位置
  1069. pGreenTemp += y * nGreenWidthBytes;
  1070. //蓝色通道图像数据指针定位到起始位置
  1071. pBlueTemp = pBlueBits;
  1072. //蓝色通道图像数据指针定位到图像数据每行的起始零位置
  1073. pBlueTemp += y * nBlueWidthBytes;
  1074. //CString s, message = "";
  1075. //列位置
  1076. for(x = 0; x < nCombineWidth; x++)
  1077. {
  1078. //进行合并操作
  1079. pCombineTemp[2] = *pRedTemp;
  1080. pCombineTemp[1] = *pGreenTemp;
  1081. pCombineTemp[0] = *pBlueTemp;
  1082. //调整图像数据指针
  1083. pCombineTemp += 3;
  1084. pRedTemp++;
  1085. pGreenTemp++;
  1086. pBlueTemp++;
  1087. }
  1088. }
  1089. return TRUE;
  1090. }