Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you scale a CBitmap object?

I've loaded a CBitmap object from a resource ID, and I'm now wanting to scale it to 50% its size in each dimension. How might I go about this?

like image 553
Smashery Avatar asked May 05 '10 05:05

Smashery


People also ask

How do you scale a bitmap image?

❓ How can I resize a BMP image? First, you need to add a BMP image file: drag & drop your BMP image file or click inside the white area to choose a file. Then adjust resize settings, and click the "Resize" button. After the process completes, you can download your result file.

Can you resize a bitmap?

You can resize your bitmap via the options by specifying the desired width and height (in pixels) of the new bitmap or drag the bitmap by its corners and adjust its size interactively. You can also preserve the aspect ratio of bitmap sides and change the dimensions proportionally.

What happens to image quality when bitmaps are scaled?

Bitmap images are organised as a grid of coloured squares called pixels (short for 'picture elements'). When zooming in or enlarging a bitmap image, the pixels are stretched and made into larger blocks. This is why bitmap images appear as poor quality when enlarged too much.


2 Answers

  1. Select your CBitmap obj into a memDC A (using CDC::SelectObject())
  2. Create a new CBitmap with desired sized and select it into another MemDC B
  3. Use CDC::stretchblt(...) to stretch bmp in MemDC A into MemDC B
  4. Deselect your CBitmap objects (by selecting what was returned from the previous calls to SelectObject)
  5. Use your new CBitmap
like image 142
SysAdmin Avatar answered Oct 05 '22 08:10

SysAdmin


Here's a worked out implementation of @Smashery's answer.

I use this to scale based on DPI, but it should be easy to adapt to arbitrary scales.

std::shared_ptr<CBitmap> AppHiDpiScaleBitmap (CBitmap &bmp)
{
    BITMAP bm = { 0 };
    bmp.GetBitmap (&bm);
    auto size = CSize (bm.bmWidth, bm.bmHeight);

    CWindowDC screenCDC (NULL);
    auto dpiX = screenCDC.GetDeviceCaps (LOGPIXELSX);
    auto dpiY = screenCDC.GetDeviceCaps (LOGPIXELSY);

    auto hiSize = CSize ((dpiX * size.cx) / 96, (dpiY * size.cy) / 96);

    std::shared_ptr<CBitmap> res (new CBitmap ());
    res->CreateCompatibleBitmap (&screenCDC, hiSize.cx, hiSize.cy);

    CDC srcCompatCDC;
    srcCompatCDC.CreateCompatibleDC (&screenCDC);
    CDC destCompatCDC;
    destCompatCDC.CreateCompatibleDC (&screenCDC);

    CMemDC srcDC (srcCompatCDC, CRect (CPoint (), size));
    auto oldSrcBmp = srcDC.GetDC ().SelectObject (&bmp);

    CMemDC destDC (destCompatCDC, CRect(CPoint(), hiSize));
    auto oldDestBmp = destDC.GetDC ().SelectObject (res.get());

    destDC.GetDC ().StretchBlt (0, 0, hiSize.cx, hiSize.cy, &srcDC.GetDC(), 0, 0, size.cx, size.cy, SRCCOPY);

    srcDC.GetDC ().SelectObject (oldSrcBmp);
    destDC.GetDC ().SelectObject (oldDestBmp);

    return res;
}
like image 31
Frank Krueger Avatar answered Oct 05 '22 06:10

Frank Krueger