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); //当前区与指定区相交区创建的一个新的裁剪区。 } } }
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);
//当前区与指定区相交区创建的一个新的裁剪区。
}
}
}
我问的是:怎样快速的将一个单色位图转为区域?要得到区域的句柄
做Skin窗体时用的
{
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;
}
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);
//.......
}
但是我觉得每次CreateRectRgn、CombineRgn效率太低了
听人说用ExtCreateRegion创建区域时填充数据块些,但是我不知道怎么填充
下面是使用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;
}