怎样快速的将一个单色位图转为区域?(白色部分为区域)
ExtCreateRegion怎么用?(MSDN我有,但具体怎样填充数据不知道,谁能用中文说明一下)

解决方案 »

  1.   

    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);
    //当前区与指定区相交区创建的一个新的裁剪区。
    }
    }
    }
      

  2.   

    ???
    我问的是:怎样快速的将一个单色位图转为区域?要得到区域的句柄
    做Skin窗体时用的
      

  3.   

    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;
    }
      

  4.   

    如果上面的结果不对的话,将下面的代码修改一下:
        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);
            //.......
        }
      

  5.   

    谢谢jishiping(JSP 季世平)提供的代码
    但是我觉得每次CreateRectRgn、CombineRgn效率太低了
    听人说用ExtCreateRegion创建区域时填充数据块些,但是我不知道怎么填充
      

  6.   

    除非你的这个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;
    }
      

  7.   

    刚才贴了好多次,才贴上去了。还是那句话,获得每行的数据指针Data,如果不对的话,就改用另外一个表达式。