使用GetPixel要注意

今天遇到一个问题,调试了一天都没有搞明白。任务是这样的:将一个bitmap图片放到一个DC里,然后获取这个DC里的某一点的RGB值。情况正如下:
  1. CFilefile;//用于读取BMP文件
  2. BITMAPFILEHEADERbfhHeader;//bmp文件头
  3. BITMAPINFOHEADERbmiHeader;//bmp格式头
  4. LPBITMAPINFOlpBitmapInfo;//bmp格式具体信息
  5. intbmpWidth=0;//图片宽度
  6. intbmpHeight=0;//图片高度
  7. if(!file.Open(filePath,CFile::modeRead))
  8. return;//打开文件
  9. //读取文件头
  10. file.Read(&bfhHeader,sizeof(BITMAPFILEHEADER));
  11. if(bfhHeader.bfType!=((WORD)('M'<<8)|'B'))//判断是否是"BM"
  12. return;
  13. if(bfhHeader.bfSize!=file.GetLength())
  14. return;
  15. //读取位图信息
  16. if(file.Read((LPSTR)&bmiHeader,sizeof(bmiHeader))!=sizeof(bmiHeader))
  17. return;
  18. bmpHeight=bmiHeader.biHeight;//得到高度和宽度
  19. bmpWidth=bmiHeader.biWidth;
  20. file.SeekToBegin();//指针移动到文件的开头
  21. file.Read(&bfhHeader,sizeof(BITMAPFILEHEADER));
  22. UINTuBmpInfoLen=(UINT)bfhHeader.bfOffBits-sizeof(BITMAPFILEHEADER);//FileSize
  23. lpBitmapInfo=(LPBITMAPINFO)newBYTE[uBmpInfoLen];//具体信息分配内存
  24. file.Read((LPVOID)lpBitmapInfo,uBmpInfoLen);
  25. if((*(LPDWORD)(lpBitmapInfo))!=sizeof(BITMAPINFOHEADER))
  26. return;
  27. DWORDdwBitlen=bfhHeader.bfSize-bfhHeader.bfOffBits;//图像数据的字节大小
  28. unsignedchar*lpSrcBits=newBYTE[dwBitlen];
  29. file.ReadHuge(lpSrcBits,dwBitlen);
  30. file.Close();//关闭文件
  31. //将文件数据加到DC里
  32. CClientDCpDC(this);
  33. //CClientDCpDC(&m_blackWhiteImage);
  34. //CDC*pDC=NULL;
  35. //HDCpDC=::CreateCompatibleDC(NULL);
  36. //::CreateCompatibleDC(pDC);
  37. intret=StretchDIBits(pDC,0,0,bmpWidth,bmpHeight,0,0,bmpWidth,bmpHeight,
  38. lpSrcBits,lpBitmapInfo,DIB_RGB_COLORS,SRCCOPY);

调试的时候,上面执行都没有问题,问题是:

int a = pDC.GetPixel(currentBit, currentLine);

a的返回值是-1,无论怎么改,都是这个值。然后没有办法,只能google,有人说调试的时候调用GetPixel会出错。我试了一下正常模式下运行,竟然通过了。真是的,都怪平时太依赖调试模式了。


几天后的更新:
原来GetPixel调用时也是可以获取正确的值的,但是要使用CompatibleDC,代码如下:
  1. if(m_hBmp!=NULL)
  2. {
  3. DeleteObject(m_hBmp);
  4. }
  5. m_hBmp=(HBITMAP)LoadImage(AfxGetInstanceHandle(),
  6. imagePath,
  7. IMAGE_BITMAP,
  8. 0,
  9. 0,
  10. LR_LOADFROMFILE);
  11. if(m_hBmp==NULL)
  12. {
  13. AfxMessageBox("无法打开指定的黑底白框图!");
  14. return;
  15. }else
  16. {
  17. BITMAPbmp;
  18. GetObject(m_hBmp,sizeof(BITMAP),&bmp);
  19. m_bmHeight=bmp.bmHeight;//得到高度和宽度
  20. m_bmWidth=bmp.bmWidth;
  21. }
  22. selectBlock=-1;
  23. //将文件数据加到DC里
  24. //CClientDCpDC(this);
  25. CDCdc;
  26. dc.CreateCompatibleDC(NULL);
  27. if(dc==NULL)
  28. {
  29. AfxMessageBox("无法创建兼容DC");
  30. return;
  31. }
  32. HBITMAPhOldBmp=(HBITMAP)SelectObject(dc,m_hBmp);
  33. blocksCount=0;
  34. //遍历各行找矩形框左上角的坐标
  35. for(intcurrentLine=1;currentLine<m_bmHeight-1;currentLine++)
  36. {
  37. for(intcurrentBit=1;currentBit<m_bmWidth-1;currentBit++)
  38. {
  39. //优化(不是必须的),提高执行效率
  40. for(inti=0;i<blocksCount;i++)
  41. {
  42. if(currentLine>=blocks[i].pos.top&&
  43. currentLine<=blocks[i].pos.bottom&&
  44. currentBit>=blocks[i].pos.left&&
  45. currentBit<=blocks[i].pos.right)
  46. {
  47. currentBit=blocks[i].pos.right+1;
  48. }
  49. }
  50. if(0x00ffffff==dc.GetPixel(currentBit,currentLine)&&//自己是白点
  51. 0x00ffffff!=dc.GetPixel(currentBit,(currentLine-1))&&//上面是不是白点
  52. 0x00ffffff==dc.GetPixel(currentBit,(currentLine+1))&&//下面是白点
  53. 0x00ffffff!=dc.GetPixel((currentBit-1),currentLine)&&//左边是不是白点
  54. 0x00ffffff==dc.GetPixel((currentBit+1),currentLine))//右边是白点
  55. //找到一个左上角
  56. {
  57. blocks[blocksCount].pos.top=currentLine;
  58. blocks[blocksCount].pos.left=currentBit;
  59. //计算按钮的高和宽
  60. UINTbottom=currentLine;
  61. for(;;bottom++)
  62. {
  63. if(0x00ffffff!=dc.GetPixel(currentBit,bottom))
  64. break;
  65. }
  66. blocks[blocksCount].pos.bottom=bottom;
  67. UINTright=currentBit;
  68. for(;;right++)
  69. {
  70. if(0x00ffffff!=dc.GetPixel(right,currentLine))
  71. break;
  72. }
  73. blocks[blocksCount].pos.right=right;
  74. blocks[blocksCount].id=-1;
  75. blocksCount++;
  76. }
  77. }
  78. }
  79. if(blocksCount==0)
  80. {
  81. AfxMessageBox("无法检测到白框");
  82. }
  83. (HBITMAP)SelectObject(dc,hOldBmp);
  84. dc.DeleteDC();
这种情况下将断点设置在 GetPixel上就没有问题了,原因是使用CreateCompatibleDC生成的DC是设备无关的,只是放在内存里,使用GetPixel获取RGB值只是读内存,而不是读界面的颜色。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值