c++mfcfreeimage

How to draw an image inside a circle?


I have a MFC application and i need to draw an image inside a circle (or crop the image in a circle).

I use FreeImage to load the image, so an answer using FreeImage or a MFC function will work.

This is how i load the image:

void DrawImage(CDC *pDC, RECT *pRect, const BYTE *pBuffer, int nBufferLength)
{
    FIMEMORY *pfmem = FreeImage_OpenMemory((BYTE*)pBuffer, nBufferLength);
    FREE_IMAGE_FORMAT fif = FreeImage_GetFileTypeFromMemory(pfmem);
    FIBITMAP *pdib = FreeImage_LoadFromMemory(fif, pfmem);  

    sz.cx = FreeImage_GetWidth(pdib);
    sz.cy = FreeImage_GetHeight(pdib);

    CRect rc(pRect);

    BITMAPINFO *pbmpi = FreeImage_GetInfo(pdib);
    BYTE *pDibBits = FreeImage_GetBits(pdib);

    ::SetDIBitsToDevice(pDC->GetSafeHdc(), 
                            rc.left, 
                            rc.top, 
                            rc.Width(), 
                            rc.Height(), 
                            0, 
                            0, 
                            0, 
                            rc.Height(), 
                            pDibBits, 
                            pbmpi, 
                            DIB_RGB_COLORS);

    FreeImage_Unload(pdib);
    FreeImage_CloseMemory(pfmem);
}

Solution

  • Posting my answer in case someone runs in the same problem, it was quite easy actually just did what @Karthik Krish wrote:

    //  Get the rect of a circle in the center o the image.
    CRect rectMask(pRect);
    
    int cx = rectMask.Width();
    int cy = rectMask.Heigth();
    
    if (cx > cy)
    {
        rectMask.left += (cx - cy) / 2;
        rectMask.right = rectMask.left + cy;
    }
    else
    {
        rectMask.top += (cy - cx) / 2;
        rectMask.bottom = rectMask.top + cx;
    }
    
    HRGN hRegiaoClip = NULL;
    
    //  Create a region for the circle
    hRegiaoClip = ::CreateEllipticRgnIndirect(&rectMask);
    
    //  Select circle in the Device context.
    ::SelectClipRgn(pDC->GetSafeHdc(), hRegiaoClip);
    
    //  Call function to draw the image (the one in the question).
    DrawImage(pDC, pRect, pImgBytes, pSerial->GetImageBufferSize(), TRUE);
    
    //  Clean up
    ::SelectClipRgn(pDC->GetSafeHdc(), NULL);
    ::DeleteObject(hRegiaoClip);