Как нарисовать изображение внутри круга?

У меня есть приложение MFC, и мне нужно нарисовать изображение внутри круга (или обрезать изображение по кругу).

Я использую FreeImage для загрузки изображения, поэтому ответ с использованием FreeImage или функции MFC будет работать.

Вот как я загружаю изображение:

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

person Penachia    schedule 20.02.2018    source источник
comment
Руководство по отсечению областей WIN32 и просто создать объявление области эллипса, выбрать его как область клипа CreateEllipticRgnIndirect   -  person Mihayl    schedule 20.02.2018
comment
Вам нужно какое-то сглаживание?   -  person IInspectable    schedule 21.02.2018
comment
@IInspectable нет, просто обрежьте изображение по кругу.   -  person Penachia    schedule 21.02.2018
comment
Создайте круглую область и нарисуйте на ней.   -  person Karthik Krish    schedule 23.02.2018


Ответы (1)


Публикация моего ответа на случай, если кто-то столкнется с той же проблемой, на самом деле было довольно просто, просто сделал то, что написал @Karthik Krish:

//  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);
person Penachia    schedule 23.02.2018