CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 15 of 20

Thread: [RESOLVED] GDI - can i speed up the DIB code?

Threaded View

  1. #1
    Join Date
    Apr 2009
    Posts
    1,298

    [RESOLVED] GDI - can i speed up the DIB code?

    i have these 2 functions for create regions:
    Code:
    BYTE* Get24BitPixels(HBITMAP pBitmap, WORD *pwWidth, WORD *pwHeight)
        {
            // a bitmap object just to get bitmap width and height
            BITMAP bmpBmp;
    
            // pointer to original bitmap info
            LPBITMAPINFO pbmiInfo;
    
            // bitmap info will hold the new 24bit bitmap info
            BITMAPINFO bmiInfo;
    
            // width and height of the bitmap
            WORD wBmpWidth, wBmpHeight;
    
            // ---------------------------------------------------------
            // get some info from the bitmap
            // ---------------------------------------------------------
            GetObject(pBitmap, sizeof(bmpBmp),&bmpBmp);
            pbmiInfo   = (LPBITMAPINFO)&bmpBmp;
    
            // get width and height
            wBmpWidth  = (WORD)pbmiInfo->bmiHeader.biWidth;
            wBmpWidth -= (wBmpWidth%4);                       // width is 4 byte boundary aligned.
            wBmpHeight = (WORD)pbmiInfo->bmiHeader.biHeight;
    
            // copy to caller width and height parms
            *pwWidth  = wBmpWidth;
            *pwHeight = wBmpHeight;
            // ---------------------------------------------------------
    
            // allocate width * height * 24bits pixels
            //BYTE *pPixels = new BYTE[wBmpWidth*wBmpHeight*3];
            BYTE *pPixels = new (std::nothrow) BYTE[wBmpWidth*wBmpHeight*3];
            if (pPixels==0)
                return NULL;
    
            // get user desktop device context to get pixels from
            HDC hDC = GetWindowDC(NULL);
    
            // fill desired structure
            bmiInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
            bmiInfo.bmiHeader.biWidth = wBmpWidth;
            bmiInfo.bmiHeader.biHeight = -wBmpHeight;
            bmiInfo.bmiHeader.biPlanes = 1;
            bmiInfo.bmiHeader.biBitCount = 24;
            bmiInfo.bmiHeader.biCompression = BI_RGB;
            bmiInfo.bmiHeader.biSizeImage = wBmpWidth*wBmpHeight*3;
            bmiInfo.bmiHeader.biXPelsPerMeter = 0;
            bmiInfo.bmiHeader.biYPelsPerMeter = 0;
            bmiInfo.bmiHeader.biClrUsed = 0;
            bmiInfo.bmiHeader.biClrImportant = 0;
    
            // get pixels from the original bitmap converted to 24bits
            int iRes = GetDIBits(hDC,pBitmap,0,wBmpHeight,(LPVOID)pPixels,&bmiInfo,DIB_RGB_COLORS);
    
            // release the device context
            ReleaseDC(NULL,hDC);
    
            // if failed, cancel the operation.
            if (!iRes)
            {
                delete[] pPixels;
                return NULL;
            };
    
            // return the pixel array
            return pPixels;
        }
    
        HRGN RegionbyBitmap(HBITMAP pBitmap,COLORREF clrTransparent=-1 )
        {
            BYTE jTranspR = GetRValue(clrTransparent), jTranspG=GetGValue(clrTransparent), jTranspB=GetBValue(clrTransparent);
            // bitmap width and height
            WORD wBmpWidth,wBmpHeight;
    
            // the final region and a temporary region
            HRGN hRgn, hTmpRgn;
    
            // 24bit pixels from the bitmap
            BYTE *pPixels = Get24BitPixels(pBitmap, &wBmpWidth, &wBmpHeight);
            if (!pPixels) return NULL;
    
            // create our working region
            hRgn = CreateRectRgn(0,0,wBmpWidth,wBmpHeight);
            if (!hRgn)
            {
                delete[] pPixels;
                return NULL;
            }
    
            // ---------------------------------------------------------
            // scan the bitmap
            // ---------------------------------------------------------
    
    
            DWORD p=0;
            for (WORD y=0; y<wBmpHeight; y++)
            {
                for (WORD x=0; x<wBmpWidth; x++)
                {
                  BYTE jRed   = pPixels[p+2];
                  BYTE jGreen = pPixels[p+1];
                  BYTE jBlue  = pPixels[p+0];
    
                  if ((jRed == jTranspR && jGreen == jTranspG && jBlue == jTranspB))
                  {
                    // remove transparent color from region
                    hTmpRgn = CreateRectRgn(x,y,x+1,y+1);
                    CombineRgn(hRgn, hRgn, hTmpRgn, RGN_XOR);
                    DeleteObject(hTmpRgn);
    
    
                  }
    
                  // next pixel
                  p+=3;
                }
            }
    
            // release pixels
            delete[] pPixels;
    
            return hRgn;
        }
    they work fine. but if i have images with 100X40, it can be very slow
    so imagine if the control region is 200X200.
    anotherthing: whe it's very slow(i use a timer on animation), i can lose the window control messages(freezes the application).
    can i speed up the DIB's code?
    Last edited by Cambalinho; July 24th, 2015 at 08:39 AM.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  


Windows Mobile Development Center


Click Here to Expand Forum to Full Width




On-Demand Webinars (sponsored)