Solved

Whats the best way to scale a windows bitmap?

Posted on 2015-01-10
3
347 Views
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.

Thanks,
JohnB
0
Comment
Question by:jxbma
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 2
3 Comments
 
LVL 31

Expert Comment

by:Zoppo
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,

ZOPPO
0
 
LVL 1

Author Comment

by:jxbma
ID: 40558889
Zoppo:

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?

Thanks,
JB
0
 
LVL 31

Accepted Solution

by:
Zoppo earned 500 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

ZOPPO
0

Featured Post

On Demand Webinar: Networking for the Cloud Era

Ready to improve network connectivity? Watch this webinar to learn how SD-WANs and a one-click instant connect tool can boost provisions, deployment, and management of your cloud connection.

Question has a verified solution.

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

For most people, the WrapPanel seems like a magic when they switch from WinForms to WPF. Most of us will think that the code that is used to write a control like that would be difficult. However, most of the work is done by the WPF engine, and the W…
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 goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…

626 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