none
loading a rounded bitmap on Dialog RRS feed

  • Question

  • Hi All,

    I am facing an issue, please guide me in fixing.

    I am working on a dialog based MFC application using VS2008.

    On my Dialog I want to load a bitmap file on a picture control.

    The bitmap image size is 32 * 32.

    It is a square image and inside that square there is a circle which is touching all the boundaries of square.

    Requirement is, I need to load the circular image(i.e. only the circle should be visible on the dialog, not the square)

    How can I ignore all 4 corners of square from displaying on dialog?

    Please guide me in achieving this. 

    Thanks in Advance,


    Thanks & Regards, Mayank Agarwal

    Wednesday, March 11, 2015 11:03 AM

Answers

  • i thing you want to use transparent bitmap if so.

    here is link

    and source Example

    DrawTransparent(CDC * pDC, int x, int y, HBITMAP hBitmap) { COLORREF crOldBack = pDC->SetBkColor(RGB(255,255,255)); COLORREF crOldText = pDC->SetTextColor(0); CDC dcImage, dcTrans; // Create two memory dcs for the image and the mask dcImage.CreateCompatibleDC(pDC); dcTrans.CreateCompatibleDC(pDC); // Select the image into the appropriate dc CBitmap* pOldBitmapImage = dcImage.SelectObject(pOldBitmapImage->FromHandle(hBitmap)); // Create the mask bitmap CBitmap bitmapTrans; BITMAP bm; ::GetObject( hBitmap, sizeof( bm ), &bm ); int nWidth = bm.bmWidth; int nHeight = bm.bmHeight; bitmapTrans.CreateBitmap(nWidth, nHeight, 1, 1, NULL); // Select the mask bitmap into the appropriate dc CBitmap* pOldBitmapTrans = dcTrans.SelectObject(&bitmapTrans); // Build mask based on transparent colour dcImage.SetBkColor(RGB(255,255,255)); dcTrans.BitBlt(0, 0, nWidth, nHeight, &dcImage, 0, 0, SRCCOPY); // Do the work - True Mask method - cool if not actual display pDC->BitBlt(x, y, nWidth, nHeight, &dcImage, 0, 0, SRCINVERT); pDC->BitBlt(x, y, nWidth, nHeight, &dcTrans, 0, 0, SRCAND); pDC->BitBlt(x, y, nWidth, nHeight, &dcImage, 0, 0, SRCINVERT); // Restore settings dcImage.SelectObject(pOldBitmapImage); dcTrans.SelectObject(pOldBitmapTrans); pDC->SetBkColor(crOldBack); pDC->SetTextColor(crOldText);

    }


    • Marked as answer by Shu 2017 Tuesday, March 24, 2015 2:41 AM
    Wednesday, March 11, 2015 11:59 AM
  • The Picture Control part is what is going to trip you up.  In essence, child windows like CStatic (the MFC class that is a Picture Control) are opaque rectangles and there isn't a lot you can do about it.

    You can use SetWindowRgn to clip your picture box, but you likely won't be happy with the result.  For one, SetWindowRgn is limited to pixel boundaries, which will result in a jagged circle.  It also doesn't support partial transparency.

    Amrit's answer is one approach, although that code is based on very old versions of Windows that lack TransparentBlt (TransparentBlt does the same thing and avoids the flicker that Amrit's DrawTransparent will exhibit and in most scenarios TransparentBlt is faster).

    The general idea with Amrit's answer is to avoid the Picture control altogether and just draw the circle as part of the dialog's OnPaint.  Since you avoid the child control, you can draw anything you want without regard to rectangular shapes.

    To go a step farther, I would probably avoid TransparentBlt/DrawTransparent which will still suffer from jagged edges and go with AlphaBlend or Graphics::DrawImage (from GDI+).  In this world you would use a 32 bit image with alpha transparency (usually in the form of a .PNG file).  There are lots of examples of loading an image with GDI+ and drawing it.  Plug that into your Dialog's OnPaint and you will probably have what you want.

    • Marked as answer by Shu 2017 Tuesday, March 24, 2015 2:41 AM
    Wednesday, March 11, 2015 2:41 PM

All replies

  • i thing you want to use transparent bitmap if so.

    here is link

    and source Example

    DrawTransparent(CDC * pDC, int x, int y, HBITMAP hBitmap) { COLORREF crOldBack = pDC->SetBkColor(RGB(255,255,255)); COLORREF crOldText = pDC->SetTextColor(0); CDC dcImage, dcTrans; // Create two memory dcs for the image and the mask dcImage.CreateCompatibleDC(pDC); dcTrans.CreateCompatibleDC(pDC); // Select the image into the appropriate dc CBitmap* pOldBitmapImage = dcImage.SelectObject(pOldBitmapImage->FromHandle(hBitmap)); // Create the mask bitmap CBitmap bitmapTrans; BITMAP bm; ::GetObject( hBitmap, sizeof( bm ), &bm ); int nWidth = bm.bmWidth; int nHeight = bm.bmHeight; bitmapTrans.CreateBitmap(nWidth, nHeight, 1, 1, NULL); // Select the mask bitmap into the appropriate dc CBitmap* pOldBitmapTrans = dcTrans.SelectObject(&bitmapTrans); // Build mask based on transparent colour dcImage.SetBkColor(RGB(255,255,255)); dcTrans.BitBlt(0, 0, nWidth, nHeight, &dcImage, 0, 0, SRCCOPY); // Do the work - True Mask method - cool if not actual display pDC->BitBlt(x, y, nWidth, nHeight, &dcImage, 0, 0, SRCINVERT); pDC->BitBlt(x, y, nWidth, nHeight, &dcTrans, 0, 0, SRCAND); pDC->BitBlt(x, y, nWidth, nHeight, &dcImage, 0, 0, SRCINVERT); // Restore settings dcImage.SelectObject(pOldBitmapImage); dcTrans.SelectObject(pOldBitmapTrans); pDC->SetBkColor(crOldBack); pDC->SetTextColor(crOldText);

    }


    • Marked as answer by Shu 2017 Tuesday, March 24, 2015 2:41 AM
    Wednesday, March 11, 2015 11:59 AM
  • The Picture Control part is what is going to trip you up.  In essence, child windows like CStatic (the MFC class that is a Picture Control) are opaque rectangles and there isn't a lot you can do about it.

    You can use SetWindowRgn to clip your picture box, but you likely won't be happy with the result.  For one, SetWindowRgn is limited to pixel boundaries, which will result in a jagged circle.  It also doesn't support partial transparency.

    Amrit's answer is one approach, although that code is based on very old versions of Windows that lack TransparentBlt (TransparentBlt does the same thing and avoids the flicker that Amrit's DrawTransparent will exhibit and in most scenarios TransparentBlt is faster).

    The general idea with Amrit's answer is to avoid the Picture control altogether and just draw the circle as part of the dialog's OnPaint.  Since you avoid the child control, you can draw anything you want without regard to rectangular shapes.

    To go a step farther, I would probably avoid TransparentBlt/DrawTransparent which will still suffer from jagged edges and go with AlphaBlend or Graphics::DrawImage (from GDI+).  In this world you would use a 32 bit image with alpha transparency (usually in the form of a .PNG file).  There are lots of examples of loading an image with GDI+ and drawing it.  Plug that into your Dialog's OnPaint and you will probably have what you want.

    • Marked as answer by Shu 2017 Tuesday, March 24, 2015 2:41 AM
    Wednesday, March 11, 2015 2:41 PM