积极答复者
如何在内存DC中调用GetPixel获取像素点颜色值?

问题
-
由于文字背景色为白色,前景色为黑色,于是我在窗口中间绘制了16 * 16的单元格:
1、使用客户区域的窗口DC来绘图(在窗口中显示出来)
A、左边白色为绘图区域,在左上角输出了一个“鲁”字;
B、再使用GetTextExtentPoint32函数可以得出该文字为16 * 16像素大小;
C、最后使用GetPixel函数取出每个像素点的颜色值,来填充左窗口中对应的表格。
单元格的填充方法:根据左上角(最小的)“鲁”字每个像素点的颜色值,来对应填充这里单元格的颜色;
该点阵的计算方法:每个像素点用1bit表示(0表示黑,1表示白),于是这个字号的鲁字就占了16 * 16 / 2 = 32字节
按横向取,因为8bit/字节嘛,也就是一个字节要横向取8个像素点。
如下图所示:
这个方法的缺点就是DLL模块中必须要使用一个窗口句柄,然后把文字画上去再取出像素点,所以这方法欠妥。便想到了下面的方法:先创建一个虚拟DC,然后再创建一个内存DC,在内存DC中使用TextOut,但用GetPixel时,老是返回CLR_INVALID,而MSDN中一段解释也没有看明白,它说并不是所有DC都支持GetPixel,必须调用GetDeviceCaps来获取详情(在BD、GG许久后,这个API始终没看懂到底有什么用)
2、使用内存DC来输出图形
A、创建虚拟DC,再创建一个兼容的内存DC,再TextOut输出文字;(我将DC载入HBITMAP,发现全为背景的黑色)
B、再使用GetTextExtentPoint32函数可以得出该文字为16 * 16像素大小;(大小能获取到)
C、最后使用GetPixel函数取出每个像素点的颜色值,来填充左窗口中对应的表格。(这里GetPixel失败)
相关伪代码如下:
#include <windows.h> #pragma comment(lib,"user32.lib") int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR pszCmdLine, int cmdShow) { // create a virtual dc to draw elements. HDC hdcScreen = CreateDC("DISPLAY", NULL, NULL, NULL); HDC hdcCompatible = CreateCompatibleDC(hdcScreen); CString m_strText = _T("Hello"); SIZE m_sz; if(hdcCompatible == NULL) { MessageBox(NULL,_T("CreateCompatibleDC Failed !"),NULL,NULL); return NULL; } // then set the text color is black,the back color is white. SetBkColor(hdcCompatible,RGB(255,255,255)); SetTextColor(hdcCompatible,RGB(0,0,0)); // draw the text int a virtual dc. TextOut(hdcCompatible,0,0,m_strText,m_strText.GetLength()); // get the text width and height. GetTextExtentPoint32(hdcCompatible,m_strText,m_strText.GetLength(),&m_sz); // get the pixel infomation. for(int i=0; i<m_sz.cx; i++) { for(int j=0; j<m_sz.cy; j++) { COLORREF color = GetPixel(hdcCompatible,i,j); if(color == CLR_INVALID) { TRACE("call GetPixel Failed !\r\n"); } else if(color == RGB(255,255,255) { // Set the bit is 0. } else { // Set the bit is 1. } } } }
这里的color变量一直都是0x00FFFFFF(背景色),困扰半个月的问题了,希望有空的兄弟帮忙看看这个问题如何解决,或者有更好的方法,不盛感激!
答案
-
有时在调试的时候使用GetPixel会出错,请您尝试一下正常模式下运行。看是否还存在此问题。
另外以下这篇文章是讲GetPixel出错要注意的地方,和您的问题十分相近,您可以参考下此文章。看是否有帮助。
http://blog.csdn.net/wuyao721/archive/2008/12/25/3605703.aspx
此回复包含了指向第三方的网址信息. Microsoft提供此链接以帮助您了解更多信息.此链接不受控于Microsoft且此链接包含的任何软件与信息未经验证.故Microsoft无法保证其质量,安全性以及稳定性.从互联网获取软件与信息有潜在的危险, Microsoft提醒您知悉此风险.
如果您的问题还存在,我建议你可以使用其他的方法来代替GetPixel方法。
比如我们可以用CreateDIBSection创建一个HBITMAP,它给你返回图像缓冲区的地址。创建一个内存DC,把这个DIBSECTION的HBITMAP选入DC,把你的图片绘制到这个DC,图像缓冲区中就是图片数据了。
如果我的回答有什么问题,您可以提出。
谢谢您的理解,
Lucy
Lucy Liu [MSFT]
MSDN Community Support | Feedback to us
Get or Request Code Sample from Microsoft
Please remember to mark the replies as answers if they help and unmark them if they provide no help.
- 已标记为答案 Koma.Walk 2011年4月18日 1:00
全部回复
-
Not all devices support the GetPixel function. For more information, see the RC_BITBLT raster capability under the GetDeviceCaps member function.
A bitmap must be selected within the device context, otherwise, CLR_INVALID is returned on all pixels.
Visual C++ enthusiast, like network programming and driver development. At present is being engaged in the WinCE/Windows Mobile platform embedded development. -
有时在调试的时候使用GetPixel会出错,请您尝试一下正常模式下运行。看是否还存在此问题。
另外以下这篇文章是讲GetPixel出错要注意的地方,和您的问题十分相近,您可以参考下此文章。看是否有帮助。
http://blog.csdn.net/wuyao721/archive/2008/12/25/3605703.aspx
此回复包含了指向第三方的网址信息. Microsoft提供此链接以帮助您了解更多信息.此链接不受控于Microsoft且此链接包含的任何软件与信息未经验证.故Microsoft无法保证其质量,安全性以及稳定性.从互联网获取软件与信息有潜在的危险, Microsoft提醒您知悉此风险.
如果您的问题还存在,我建议你可以使用其他的方法来代替GetPixel方法。
比如我们可以用CreateDIBSection创建一个HBITMAP,它给你返回图像缓冲区的地址。创建一个内存DC,把这个DIBSECTION的HBITMAP选入DC,把你的图片绘制到这个DC,图像缓冲区中就是图片数据了。
如果我的回答有什么问题,您可以提出。
谢谢您的理解,
Lucy
Lucy Liu [MSFT]
MSDN Community Support | Feedback to us
Get or Request Code Sample from Microsoft
Please remember to mark the replies as answers if they help and unmark them if they provide no help.
- 已标记为答案 Koma.Walk 2011年4月18日 1:00
-
有时在调试的时候使用GetPixel会出错,请您尝试一下正常模式下运行。看是否还存在此问题。
另外以下这篇文章是讲GetPixel出错要注意的地方,和您的问题十分相近,您可以参考下此文章。看是否有帮助。
http://blog.csdn.net/wuyao721/archive/2008/12/25/3605703.aspx
此回复包含了指向第三方的网址信息. Microsoft提供此链接以帮助您了解更多信息.此链接不受控于Microsoft且此链接包含的任何软件与信息未经验证.故Microsoft无法保证其质量,安全性以及稳定性.从互联网获取软件与信息有潜在的危险, Microsoft提醒您知悉此风险.
如果您的问题还存在,我建议你可以使用其他的方法来代替GetPixel方法。
比如我们可以用CreateDIBSection创建一个HBITMAP,它给你返回图像缓冲区的地址。创建一个内存DC,把这个DIBSECTION的HBITMAP选入DC,把你的图片绘制到这个DC,图像缓冲区中就是图片数据了。
如果我的回答有什么问题,您可以提出。
谢谢您的理解,
Lucy
Lucy Liu [MSFT]
MSDN Community Support | Feedback to us
Get or Request Code Sample from Microsoft
Please remember to mark the replies as answers if they help and unmark them if they provide no help.