GDI/GDI+中只有对字体的外边框的测量,而没有提供对点,线,面,曲线的外边框获取函数。下面是本人利用DIB技术编写的探测简单图元,甚至也可以探测自己定义的复杂图元的外边矩形框的函数。本人已经测试,效果很棒。

bool GetFeatureRange(void *object, //自己定义的图元对象
CRect rect, // DIB屏幕大小
CDC *pDC, //绘图设置
CRect &retVal // 检测范围
)
{
CDC memDC; //临时绘图设备
COLORREF bkcolor = RGB(255,255,255); // 背景色
//创建临时设备
memDC.CreateCompatibleDC(pDC);
// 建立一个与屏幕显示相同大小的DIB位图
BITMAPINFO info;
memset(&info.bmiHeader,0,sizeof(BITMAPINFOHEADER));
info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
info.bmiHeader.biWidth = rect.Width();
info.bmiHeader.biHeight = rect.Height();
info.bmiHeader.biPlanes = 1;
info.bmiHeader.biBitCount = 32;
info.bmiHeader.biCompression = BI_RGB; PVOID pBits; // 位图数据指针
HBITMAP hbitmap = CreateDIBSection(memDC.m_hDC,&info,DIB_RGB_COLORS,
&pBits,0,0);
HBITMAP hOldBitmap = (HBITMAP)memDC.SelectObject(hbitmap);
// 使用背景色清除位图
memDC.FillSolidRect(0,0,rect.Width(), rect.Height(), bkcolor); // 绘制图元
object->Draw(...);
// 还原位图
memDC.SelectObject(hOldBitmap);
// 销毁临时绘图设备
memDC.DeleteDC();
// 获取位图信息
CBitmap *pBitmap = CBitmap::FromHandle(hbitmap);
BITMAP bmp;
pBitmap->GetBitmap(&bmp);
BYTE *pixels = (BYTE*)bmp.bmBits;
// 探测范围
bool bExist = false;
// DIB存储方向有下至上 颜色存储形式BGR
BYTE r,g,b;
for(int i = 0; i < bmp.bmHeight; i++)
{
for(int j = 0; j < bmp.bmWidth; j++)
{
b = *(pixels++);
g = *(pixels++);
r = *(pixels++);
pixels++; //跳过透明度 位图像素占32位字节
if(RGB(r,g,b) != bkcolor)
{
if(bExist){
retVal.top = i;
if(retVal.left > j) retVal.left = j;
if(retVal.right < j) retVal.right = j;
}
else
{
retVal.left =
retVal.right = j;
retVal.top =
retVal.bottom = i;
bExist = true;
}
}
}
} if(bExist) //调整与屏幕相同的坐标
{
retVal.top = bmp.bmHeight - retVal.top;
retVal.bottom = bmp.bmHeight - retVal.bottom;
}
pBitmap->DeleteObject();
return bExist;
}

Windows DDB和DIB技术应用(3)--图元外边矩形检测-LMLPHP

05-04 03:21