Whats the best way to scale a windows bitmap?

Posted on 2015-01-10
Medium Priority
Last Modified: 2015-01-25
I'm working with a windows C++ app and need to apply scaling to a bitmap image which is loaded in memory.
(Windows BITMAP)

What is the best way to scale a bitmap image?
I have a windows BITMAP which I want to apply scaling to.

I do have access to the boost and opencv libraries as part of this project.

Question by:jxbma
  • 2
LVL 31

Expert Comment

ID: 40543860
Hi jxbma,

a common and easy way to do this is to create another in-memory bitmap of the wanted (scaled) size and draw the original bitmap into the new one using ::StretchBlt. To do so both bitmaps need to be selected into memory device contexts. Here's some (untested) code how this could look like:
// obtain a display DC to use as base for the memory DCs
HDC hdcScreen = ::CreateDC( "DISPLAY", NULL, NULL, NULL );

// prepare source memory DC and select the source bitmap into it
HDC hdcSource = ::CreateCompatibleDC( hdcScreen );
SIZE sSource = /*the size of the source bitmap*/
HBITMAP hBmpSource = /*the source bitmap*/;
HBITMAP hBmpOldSource = (HBITMAP)::SelectObject( hdcSource, hBmpSource );

// prepare destination memory DC, create and select the destination bitmap into it
HDC hdcDest = ::CreateCompatibleDC( hdcScreen );
SIZE sDest = /*the wanted size of the scaled target bitmap*/
HBITMAP hBmpDest = ::CreateCompatibleBitmap( hdcSource, sDest.cx, sDest.cy );
HBITMAP hBmpOldDest = (HBITMAP)::SelectObject( hdcDest, hBmpDest );

// set halft-ton stretch-blit mode for better scaling quality
::SetStretchBltMode( hdcDest, HALFTONE );

// draw the bitmap scaled into the destination memory DC
::StretchBlt( hdcDest, 0, 0, sDest.cx, sDest.cy, hdcSource, 0, 0, sSource.cx, sSource.cy, SRCCOPY );

// release everything
::SelectObject( hdcSource, hBmpOldSource );
::SelectObject( hdcDest, hBmpOldDest );
::DeleteDC( hdcSource );
::DeleteDC( hdcDest );
::DeleteDC( hdcScreen );

// now you should have the scaled bitmap in 'hBmpDest'

Open in new window

It might be you're not satisfied with the quality of the scaled bitmap - if so you should consider doing similar things using GDI+, compard with GDI it has improved drawing and smoothing/antialiasing functionality.

Hope that helps,


Author Comment

ID: 40558889

Thanks for the feedback.

Our app does image analysis. Client apps will pass us either an HBMP or LPBITMAP.
The analysis is part of a library (which will eventually get wrapped).
We don't have access to HDC's from within the library.

Is there another way to try to scale the bitmap through the windows API, or through openCv?

LVL 31

Accepted Solution

Zoppo earned 2000 total points
ID: 40559286
Hm - IMO there's nothing against using memory HDCs or GDI+ in a C++ library which uses Win32 API.

Anyway, maybe you should take a look at CxImage OpenSource lib: http://www.codeproject.com/Articles/1300/CxImage
It (beyond lot of other functionalities) has functions to scale/resample bitmaps.

Beside this if you really can't use HDCs IMO you can only use something like GetBitmapBits/SetBitmapBits to access bitmaps pixel data directly. With this you can create a new bitmap of different size and implement some algorithm to rescale the source bitmap into the new one. That shouldn't be to difficult too but is a lot of work since you have to handle all different kinds of color depths/planes yourself.

If you want to do this goole i.e. for 'image scale algorithms', you'll find some samples like i.e. http://www.compuphase.com/graphic/scale.htm


Featured Post

Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
Entering time in Microsoft Access can be difficult. An input mask often bothers users more than helping them and won't catch all typing errors. This article shows how to create a textbox for 24-hour time input with full validation politely catching …
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.
Suggested Courses

589 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question