Re: Scale bitmaps using GDI+



You cannot instantiate a Graphics object from an indexed bitmap(i.e., 8bpp).
That means you cannot scale a 8bpp source grayscale image to a new 8bpp
scaled grayscale image with gdi+.

In order to scale an indexed bitmap, you may use StretchBlt.

The approach is the same but you use GDI instead of gdi+.
1) Load the image you wish to scale as a DIB with LoadImage with the flag
LR_CREATEDIBSECTION
2) Create an empty bitmap DIB with CreateDIBSection with the new scaled
width, height and 8 bpp pixel format.
3) Select the empty bitmap into a memory device context
4) Set the destination DIB's color table with the 8bpp palette(i.e., the
bitmap to be scaled). Use SetDIBColorTable.
5) Select the source bitmap into another memory device context.
6) Use SetStretchBltMode with COLORONCOLOR and use StretchBlt to scale the
original bitmap to the new scaled bitmap.
7) Select the new scaled bitmap out of the device and the same for the
source. Cleanup the DC's(i.e.,delete them)
8) Create a gdi+ Bitmap from the scaled DIB. Use Bitmap::FromBITMAPINFO.
9) Use gdi+'s jpeg encoder to save your scaled bitmap. Keep in mind that
gdi+'s .jpeg encoder will not create a 8bpp .jpeg. It will create a 24bpp
..jpeg image.


"Eric" <Eric@xxxxxxxxxxxxxxxxxxxxxxxxx> wrote in message
news:41ECC06B-90AD-4F2C-AA65-500888B4D256@xxxxxxxxxxxxxxxx
Great suggestion!

I tried and it works in scaling full color images. When the original is a
8-bit grayscale bitmap, I get a scaled blank image instead. It seems like
the
color palette does not get to passed to the new scaled bitmap. If I do
not
scale and just save the original to file using GDIOriginalLoadedBmp->Save,
it
works. That tells me GDIOriginalLoadedBmp carries the right palette.
Doesn't
the GDIOriginalLoadedBmp->GetPixelFormat() pass the right palette to the
new
bitmap, or I need to do something more?

Thanks!
Eric


"Michael Phillips, Jr." wrote:

I would suggest this approach:
1) Load the image you want to scale.
2) Create an emtpy bitmap with the desired scaled width, height and pixel
format. The pixel format should match your loaded image.
Gdiplus::Bitmap *GDIBmp = new Gdiplus::Bitmap( m_dwNewWidth,
m_dwNewHeight, GDIOriginalLoadedBmp->GetPixelFormat());
3) Create a Graphics object from this new empty bitmap. You now have a
drawing surface which you will use to draw and scale the image that you
loaded in step1.
// create a graphics object from original bitmap
Gdiplus::Graphics GDIGrp(GDIBmp);
4) Use DrawImage with your loaded image to draw and scale to the new
image.
// perform image scaling
Gdiplus::RectF rect(0, 0, m_dwNewWidth, m_dwNewHeight);
GDIGrp.DrawImage(&GDIOriginalLoadedBmp, rect);
5) Dispose of the Graphics object that contains you new scaled image.
6) Save that image with the .jpeg encoder.
// save to file
Gdiplus::Status stat = GDIBmp->Save(szwFilePath, &imgClsid, NULL);



"Eric" <Eric@xxxxxxxxxxxxxxxxxxxxxxxxx> wrote in message
news:1E17E9DF-99C1-4EF1-BA53-C647215FCFF8@xxxxxxxxxxxxxxxx
Bellow is the code that uses Graphics to obtain a scaled bitmap. But,
the
result is only a blank bitmap with right dimension. Could you point out
which
part I did wrong over there?

// create GDI+ bitmap from the original
Gdiplus::Bitmap GDIBmp(pOriginalBmpHeader, pOriginalBmpData);

// get the JPEG image encoder
CLSID imgClsid;
int nEncoderRc = GetGDIPlusEncoderClsid(L"image/jpeg", &imgClsid);

// create a graphics object from original bitmap
Gdiplus::Graphics GDIGrp(&GDIBmp);

// perform image scaling
Gdiplus::RectF rect(0, 0, m_dwNewWidth, m_dwNewHeight);
GDIGrp.DrawImage(&GDIBmp, rect);

HDC hGrahicDC = GDIGrp.GetHDC();
CDC MemDcDest;
MemDcDest.CreateCompatibleDC(CDC::FromHandle(hGrahicDC));

CBitmap bmpDest;
bmpDest.CreateCompatibleBitmap(&MemDcDest, m_dwNewWidth,
m_dwNewHeight);

// associate the new bitmap with dc
CBitmap* pOldBmp = MemDcDest.SelectObject(&bmpDest);

// copy the scaled bitmap from Graphics' DC
MemDcDest.BitBlt(0, 0, m_dwNewWidth, m_dwNewHeight,
CDC::FromHandle(hGrahicDC), 0, 0, SRCCOPY);

// create a new scaled GDI+ bitmap
Gdiplus::Bitmap* pBmpScaled =
Gdiplus::Bitmap::FromHBITMAP((HBITMAP)bmpDest,
NULL);

// save to file
Gdiplus::Status stat = pBmpScaled->Save(szwFilePath, &imgClsid, NULL);

// clean up
MemDCDest.SelectObject(pOldBmp);
GDIGrp.ReleaseHDC(hDC);

Thanks!
Eric


"Michael Phillips, Jr." wrote:

DrawImage is not only for display. The Graphics object represents a
drawing
surface. That surface can be an image, metafile, display, printer,
etc.


"Eric" <Eric@xxxxxxxxxxxxxxxxxxxxxxxxx> wrote in message
news:257B08E6-F899-4A46-B470-FE134D432B4A@xxxxxxxxxxxxxxxx
THe purpose of the scaling is not for display. I need to save the
scaled
image in file as JPEG. That means I must bind the scaled image to a
Bitmai/Image object to do that.

Thanks!
Eric


"Michael Phillips, Jr." wrote:

Use the Graphics's method DrawImage to scale your image.

"Eric" <Eric@xxxxxxxxxxxxxxxxxxxxxxxxx> wrote in message
news:9443F4FA-B556-42C1-9EF4-24A8D421D73B@xxxxxxxxxxxxxxxx
In one of my applications, I need to perform image scaling, then
save
the
scaled image to a JPEG file. I can load the original image into a
bitmap/Image object, but, cannot find a method in these two
classes
to
do
the
scaling. Since there is no need to display it, I did not use
Graphics
class.
Any ideas?
--
Thanks!
Eric











.



Relevant Pages

  • Re: Scale bitmaps using GDI+
    ... Load the image you want to scale. ... Create a Graphics object from this new empty bitmap. ... Save that image with the .jpeg encoder. ...
    (microsoft.public.win32.programmer.gdi)
  • 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)
  • Re: Scale problem with Graphics::ScaleTransform
    ... I see no place the Graphics object is used to actually draw the bitmap. ... I want to scale a photo, so i wrote the following code: ...
    (microsoft.public.vc.mfc)
  • RE: System.Drawing.Graphics.DrawImage seems to be not exact...
    ... DrawImage using the Graphics object to scale sections, ... I sliced that Bitmap in nine parts ... top and bottom middlepart ... middlepart has a width of scaled bitmap - 10px and a height of 5px, ...
    (microsoft.public.dotnet.framework.compactframework)
  • Re: Print Preview colors
    ... Printing goes fine at every scale. ... // make compatible dc for bitmap selection ... interBM.CreateCompatibleBitmap;// final sizes ... // put the memory image into the main window DC ...
    (microsoft.public.vc.mfc)