GDI+ question: Convert TBitmap to GDI+ Bitmap

GDI+ question: Convert TBitmap to GDI+ Bitmap

Post by Binzhong Z » Sat, 22 Oct 2005 10:35:50


i all,

I am just doing some tests on GDI+ for antialiasing feature with the
following code. I have tested the way to read the test image for display in
tow different ways: 1) Read the image using GDI+ Bitmap function; 2) Read
the image using the TBitmap function and then assign it to the GDI+ Bitmap
for display. You can toggle these two mode by comment out or uncomment the
#define statement. It is interesting to note that the outcomes from these
two modes are different: If I read the bitmap using the GDI+ Bitmap
function, the GDI antialiasing feature behaves as expected, even when you
make the window size very small you still be able to properly see the grid
lines of the orginal image. However, if I switch it to the TBitmap mode, the
grin lines may disapear if I shrink the window size.

Can anyone point out where I did arong with the second mode (rading the
bitmap with TBitmap -> GDI+ Bitmap)?

In the code, I used one of my own GDIObject class which is also attached at
the end of this messsage so that one can repeat my code with no probelm.

I have put my test image "Test Grdid.BMP" at "borland.public.attachment".

Thank you,
Binzhong


//---------------------------------------------------------------------------
void __fastcall TTestWnd::FormPaint(TObject *Sender)
{

// Rendering the image in memory DC
// Create a memory dc & set its dimension
HDC memdc = ::CreateCompatibleDC(Canvas->Handle);
GDIObject MyBitmap(memdc, ::CreateCompatibleBitmap(Canvas->Handle,
ClientWidth, ClientHeight));

// set the graphic to the memdc
Gdiplus::Graphics graphics(memdc);

// Comment out the next define statement to test GDI+ loaded bitmap
#define TEST_VCLTBITMAP

#ifndef TEST_VCLTBITMAP

// Load the image using GDI+ Bitmap
Gdiplus::Bitmap image(L"Test Grid.bmp");

#else

// Load the image using VCL TBitmap and asign the bitmap to GDI+ bitmap
Graphics::TBitmap *bitmap = new Graphics::TBitmap();
bitmap->LoadFromFile("Test Grid.bmp");
Gdiplus::Bitmap image(bitmap->Handle, bitmap->Palette);

#endif

// fill the background using the brush
Gdiplus::SolidBrush brush(Gdiplus::Color(255, 255, 255));
graphics.FillRectangle(&brush, 0, 0, ClientWidth, ClientHeight);

// Draw the image
//graphics.DrawImage(&image, 0, 0, ClientWidth, ClientHeight);
graphics.DrawImage(&image, Gdiplus::Rect(20, 20, ClientWidth-40,
ClientHeight-40),
0, 0, image.GetWidth(), image.GetHeight(), Gdiplus::UnitPixel);

// Copy the memory DC drawing onto canvas dc
::BitBlt(Canvas->Handle, 0, 0, ClientWidth, ClientHeight, memdc, 0, 0,
SRCCOPY);

// Release the memory
::DeleteDC(memdc);

}



// MyGdiObj header

#ifndef MyGdiObjH
#define MyGdiObjH

class GDIObject
{
HGDIOBJ m_hOld;
HDC m_hDC;

private:
void SetGDIObject(HDC hDC, HGDIOBJ hObj);
void DeleteGDIObject();
public:
HGDIOBJ m_hObj;
GDIObject(HDC hDC, HGDIOBJ hObj);
void SetNewGDIObject(HDC hDC, HGDIOBJ hObj);
~GDIObject();
};


#endif

// MyGdiObj Implementation


#include "MyGdiObj.h"
#include <stdio.h>
#include <assert.h>



///////////////////////////////////////////////////////////////////////////////
GDIObject::GDIObject(HDC hDC, HGDIOBJ hObj)
{
SetGDIObject(hDC, hObj);
}
////////////////////////////////////////
 
 
 

GDI+ question: Convert TBitmap to GDI+ Bitmap

Post by Team » Sun, 23 Oct 2005 11:07:44

Hi Binzhong,
I can reproduce your observations, and it seems that GDI+ is
inconsistent in the way it renders bitmaps depending on the source of
the bitmap and/or on any modifications made to the bitmap. For example,
at first I thought that the artifacts had something to do with the
resolution of the bitmap (i.e., the DPI info that's stored in the BMP
file), so I added this code before the call to DrawImage()...

image.SetResolution(
image.GetHorizontalResolution(),
image.GetVerticalResolution()
);

After adding this code, both the image loaded using GDI+ and the image
loaded using the TBitmap class show the aliasing artifacts you
described. This is weird because the resolution doesn't change after
the above call, yet somehow adding the above call causes GDI+ to skip
its antialiasing code. In any event, the solution is to explicitly set
the antialiasing mode...

graphics.SetInterpolationMode(
Gdiplus::InterpolationModeHighQualityBicubic
);

You'd do this before calling DrawImage(). (Note that you could also
specify InterpolationModeHighQualityBilinear.)

Good luck,
C++Builder Developer's Journal
http://www.yqcomputer.com/
BCB Commonly Asked Questions
http://www.yqcomputer.com/



1) Read the image using GDI+ Bitmap function; 2) Read