Solved

Whats the best way to scale a windows bitmap?

Posted on 2015-01-10
3
296 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

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

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

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 …
Whether you've completed a degree in computer sciences or you're a self-taught programmer, writing your first lines of code in the real world is always a challenge. Here are some of the most common pitfalls for new programmers.
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.
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…

726 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