▁▂▃▄▅▆▇█ 怎样快速的将一个单色位图转为区域?ExtCreateRegion怎么用? █▇▆▅▄▃▂▁

zyl910 2002-12-24 11:15:20
怎样快速的将一个单色位图转为区域?(白色部分为区域)
ExtCreateRegion怎么用?(MSDN我有,但具体怎样填充数据不知道,谁能用中文说明一下)
...全文
157 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
JoshuaLi 2002-12-27
  • 打赏
  • 举报
回复
up
jishiping 2002-12-26
  • 打赏
  • 举报
回复
刚才贴了好多次,才贴上去了。还是那句话,获得每行的数据指针Data,如果不对的话,就改用另外一个表达式。
jishiping 2002-12-26
  • 打赏
  • 举报
回复
除非你的这个Bitmap很大,否则速度还是很快的。
下面是使用ExtCreateRegion的代码:

#define MAXNUM 4096
HRGN GetBmpRgn(HBITMAP hBitmap)
{
int x1,x2;
int nBit;
int Size;
HRGN hRgn;
BYTE *Data;
BITMAP Bmp;
RECT *pRect;
char* buf;
RGNDATA* pRgnData;

if (GetObject(hBitmap,sizeof(
Bmp),&Bmp)==0)
return NULL;
if (Bmp.bmBitsPixel != 1) {
return NULL; //不是单色的位图
}
if (Bmp.bmBits == NULL)
return NULL;

Size = sizeof(RGNDATAHEADER)+MAXNUM
*sizeof(RECT);
if ((buf=new char[Size])==NULL)
return NULL; //没有内存
pRgnData = (RGNDATA*)buf;
pRect = (RECT*)pRgnData->Buffer;
memset(&pRgnData->rdh, 0, sizeof(
RGNDATAHEADER));
pRgnData->rdh.dwSize = sizeof(
RGNDATAHEADER);
pRgnData->rdh.iType = RDH_RECTANGLES;
pRgnData->rdh.rcBound.right = Bmp.bmWidth;
pRgnData->rdh.rcBound.bottom = Bmp.bmHeight;
for(int h=0; h<Bmp.bmHeight; h++) {
Data = (BYTE*)Bmp.bmBits+(Bmp.bmHeight
-1-h)*((Bmp.bmWidthBytes+3)/4*4);
for(nBit=7,x1=0; x1<Bmp.bmWidth; ) {
//首先查找白点
for(; x1<Bmp.bmWidth; x1++,nBit--) {
if (nBit < 0) {
nBit = 7; Data++;
}
if ((*Data>>nBit) & 1)
break; //找到白点
}
//然后查找黑点
for(x2=x1+1,nBit--; x2<Bmp.bmWidth;
x2++,nBit--) {
if (nBit < 0) {
nBit = 7; Data++;
}
if (((*Data>>nBit)&1)==0)
break; //找到黑点
}
if (x1 < Bmp.bmWidth) {
pRect->left = x1;
pRect->right = x2;
pRect->top = h;
pRect->bottom = h+1;
pRgnData->rdh.nCount++;
if (pRgnData->rdh.nCount
==MAXNUM) {
h = Bmp.bmHeight;
break; //矩形数目已经达到最大数目
}
pRect++; x1 = x2+1; nBit--;
}
}
}
hRgn = ExtCreateRegion(NULL, Size, pRgnData);
delete []buf; return hRgn;
}
zyl910 2002-12-26
  • 打赏
  • 举报
回复
谢谢jishiping(JSP 季世平)提供的代码


但是我觉得每次CreateRectRgn、CombineRgn效率太低了
听人说用ExtCreateRegion创建区域时填充数据块些,但是我不知道怎么填充
jishiping 2002-12-26
  • 打赏
  • 举报
回复
如果上面的结果不对的话,将下面的代码修改一下:
for(int h=0; h<Bmp.bmHeight; h++) {
Data = (BYTE*)Bmp.bmBits+(Bmp.bmHeight
-1-h)*Bmp.bmWidthBytes;
//.......
}
将它改成:
for(int h=0; h<Bmp.bmHeight; h++) {
Data = (BYTE*)Bmp.bmBits+(Bmp.bmHeight
-1-h)*((Bmp.bmWidthBytes+3)/4*4);
//.......
}
jishiping 2002-12-25
  • 打赏
  • 举报
回复
HRGN GetBmpRgn(HBITMAP hBitmap)
{
int x1,x2;
int nBit;
HRGN hRgn0;
HRGN hRgn1;
HRGN hRgn2;
BYTE *Data;
BITMAP Bmp;

if (GetObject(hBitmap,sizeof(
Bmp),&Bmp)==0)
return NULL;
if (Bmp.bmBitsPixel != 1) {
return NULL; //不是单色的位图
}

hRgn0 = NULL;
for(int h=0; h<Bmp.bmHeight; h++) {
Data = (BYTE*)Bmp.bmBits+(Bmp.bmHeight
-1-h)*Bmp.bmWidthBytes;
for(nBit=7,x1=0; x1<Bmp.bmWidth; ) {
//首先查找白点
for(; x1<Bmp.bmWidth; x1++,nBit--) {
if (nBit < 0) {
nBit = 7; Data++;
}
if ((*Data>>nBit) & 1)
break; //找到白点
}
//然后查找黑点
for(x2=x1+1,nBit--; x2<Bmp.bmWidth;
x2++,nBit--) {
if (nBit < 0) {
nBit = 7; Data++;
}
if (((*Data>>nBit)&1)==0)
break; //找到黑点
}
if (x1 < Bmp.bmWidth) {
hRgn1 = CreateRectRgn(x1, h,
x2, h+1);
if (hRgn0 == NULL)
hRgn0 = hRgn1;
else {
CombineRgn(hRgn0, hRgn0,
hRgn1, RGN_OR);
DeleteObject(hRgn1);
}
x1 = x2+1; nBit--;
}
}
}
return hRgn0;
}
zyl910 2002-12-25
  • 打赏
  • 举报
回复
???


我问的是:怎样快速的将一个单色位图转为区域?

要得到区域的句柄
做Skin窗体时用的
商海连横 2002-12-24
  • 打赏
  • 举报
回复
@_@
zswzwy 2002-12-24
  • 打赏
  • 举报
回复
CDC dc;
CDC* pDrawDC = pDC;
CBitmap bitmap;
CBitmap* pOldBitmap;

// only paint the rect that needs repainting
CRect client;
pDC->GetClipBox(client);
//--------------------------------------------------- if (!pDC->IsPrinting()) //如果没有使用打印机
{
// draw to offscreen bitmap for fast looking repaints
if (dc.CreateCompatibleDC(pDC)) //创建一个与其它设备相兼容的内存设备表,可在内存中准备图像
{
if (bitmap.CreateCompatibleBitmap(pDC, rect.Width(), rect.Height())) //初始化一个与pDC相容的位图,作为PDC指定的设备相
//容的任何内存设备的当前位图
{
OnPrepareDC(&dc, NULL); //为打印预览调用ONDRAW OR ONPAINT 函数之前

pDrawDC = &dc; //CDC类的对象附值给CDC的指针

// offset origin more because bitmap is just piece of the whole drawing
dc.OffsetViewportOrg(-rect.left, -rect.top); //修改视口原点坐标
pOldBitmap = dc.SelectObject(&bitmap);
dc.SetBrushOrg(rect.left % 8, rect.top % 8); //指定下一个进入设备环境的画刷的原点坐标

// might as well clip to the same rectangle
dc.IntersectClipRect(client);
//当前区与指定区相交区创建的一个新的裁剪区。
}
}
}

19,469

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 图形处理/算法
社区管理员
  • 图形处理/算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧