How to scale a bitmap

Tech Tip: Click here to run a free scan for Windows Errors and optimize PC performance

From: M Murdock (kcodrumcm_at_skrowtenevom.moc)
Date: 03/09/04


Date: Tue, 9 Mar 2004 11:11:07 -0800

Hello,

My MFC/C++ application renders a sequence of 320x240
bitmap images onto the screen using bitblt. More accurately,
I have a CDialog-derived object on which I have placed a
Picture control. I associate a bitmap with this control, which is
referred to below in the code as the "stage" object. My app
bitblits a sequence of bitmaps onto the stage. And it works fine,
which is a miracle since I understand very little about the GDI
api. But now I need to scale each image to appear larger on the
screen, full screen, if possible. I know this is going to look awful.
But I need to do it anyway. And I am hoping that I don't have to
write the scaler myself. I must avoid DirectX if it means my
Win98 user will need to do a download before running my app.

Question 1: Is there a way with the GDI api to scale up my
320x240 image on the display screen to say 640x480?

Question 2: What if I didn't mind that the resulting image
would look awful and I wanted to scale up my 320x240 image
to the user's full screen. Is that possible?

Question 3: How do I get the coordinates of the user's screen?
For the full-screen rendering scenario, is it possible to just
change the user's screen resolution to my image size? (I know
I can't change the resolution of the user's screen down as low
as 320x240. But what if my native image size was 640x480, is
changing the user's screen resolution down to 640x480 the best
way to render that image full-screen?)

When I say "scale" I mean that I would double the image size on
the user's screen by taking each pixel, X, and create 3 neighbor
pixels, Y, all with that same X pixel value,

        X -- becomes -> XY
                                YY

I just assumed that there was some GDI function for doing this
better and faster than me writing it from scratch. But I can't
find such a scaling function.

So that you will know how I am currently using GDI, I have listed
my rendering code below.
 
Thank you very much for your ideas and thoughts,

~Michael.
Move Networks
Use a mirror: kcodrumcm@skrowtenevom.moc

-----------------------------------------------------------------
This is how I currently do the rendering for
one frame:

// -----------------------------------------------------------------
// The following variables are NOT declarations. I am just
// listing variables that were set up elsewhere, and for
// clarity, indicating their types.
// ----------------------------------------------------------------
CStatic stage;
RECT rectStage;
CPoint topLeftPoint;
CWnd *pConsoleCWnd;
HWND hWnd;
HDC hdcWnd;
HDC hdcBlit;
HANDLE hDibSection;
BITMAPINFOHEADER *pbmiHeader;
CPlayerConsole *pPlayerConsole;
BYTE *pbVideoFormat;
BYTE *pbBits;
LPSTR lpMyFrameData;

// -------------------------------------------------------------
// Code to set up the render stage.
// ------------------------------------------------------------
stage.GetClientRect(&rectStage);
stage.ClientToScreen(&rectStage);
stage.ScreenToClient(&rectStage);

topLeftPoint.x = stage.left;
topLeftPoint.y = stage.top;

HWND hWnd = pPlayerConsole->m_pConsoleCWnd->m_hWnd;
WMVIDEOINFOHEADER *pvih = pbVideoFormat;
BITMAPINFOHEADER *pbmi = &(pvih->bmiHeader);

// Save the bitmap info header into a member variable for later use
CopyBIH(&pbmiHeader, pbmi);

//Get the DC
hdcWnd = GetDC(hWnd);

// Create a compatible DC
hdcBlit = CreateCompatibleDC(hdcWnd);

// Create DIBSection
hDibSection = CreateDIBSection(hdcBlit,pbmiHeader,DIB_RGB_COLORS,&pbBits,NULL,NULL);

// -------------------------------------------------------
// Code to "render" a single frame
// -------------------------------------------------------
memcpy(pbBits, lpMyFrameData, dwBufferLength);
HGDIOBJ hGDIObj = SelectObject(hdcBlit, hDibSection);
BitBlit(hdcWnd,
        topLeftPoint.x,
        topLeftPoint.y,
        pbmiHeader->biWidth,
        pbmiHeader->biHeight,
        hdcBlit,
        0,
        0,
        SRCCOPY);



Relevant Pages

  • Re: From GDI+ to DirectX
    ... I'm about as new at DirectX as can be, though I am a seasoned application ... have a .Net bitmap object. ... or is its performance boost mainly in rendering to the screen? ... Now do realize that all the drawing commands available to you in GDI+ ...
    (microsoft.public.win32.programmer.directx.managed)
  • Re: From GDI+ to DirectX
    ... I'm about as new at DirectX as can be, though I am a seasoned application ... have a .Net bitmap object. ... or is its performance boost mainly in rendering to the screen? ... Now do realize that all the drawing commands available to you in GDI+ ...
    (microsoft.public.win32.programmer.directx.managed)
  • Re: Efficient visualization of pixmaps
    ... single thread that's rendering your bitmap. ... of computation just to get the color of a single pixel. ... discover that parallelizing the bitmap rendering might give you enough ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: Interested in embedding Mozilla/Firefox in your Delphi apps w/outActiveX?
    ... What does the browser ... LLMozLib takes care of rendering the bitmap offscreen, ... I believe they made that choice because they are rendering to OpenGL ... Anyway, using this approach, I can produce all the html in memory ...
    (borland.public.delphi.thirdpartytools.general)
  • Re: Scale bitmaps using GDI+
    ... "Michael Phillips, Jr." ... In order to scale an indexed bitmap, ... The approach is the same but you use GDI instead of gdi+. ...
    (microsoft.public.win32.programmer.gdi)