Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

Whats the best way to scale a windows bitmap?

Posted on 2015-01-10
3
Medium Priority
?
380 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 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

ZOPPO
0

Featured Post

Free learning courses: Active Directory Deep Dive

Get a firm grasp on your IT environment when you learn Active Directory best practices with Veeam! Watch all, or choose any amount, of this three-part webinar series to improve your skills. From the basics to virtualization and backup, we got you covered.

Question has a verified solution.

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

IntroductionThis article is the second in a three part article series on the Visual Studio 2008 Debugger.  It provides tips in setting and using breakpoints. If not familiar with this debugger, you can find a basic introduction in the EE article loc…
As more and more people are shifting to the latest .Net frameworks, the windows presentation framework is gaining importance by the day. Many people are now turning to WPF controls to provide a rich user experience. I have been using WPF controls fo…
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.
This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA. http://www.experts-exchange.com/videos/1478/Excel-Error-Handlin…

721 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