Click here to Skip to main content
15,878,953 members
Please Sign up or sign in to vote.
4.00/5 (1 vote)
See more:
Hi all.
I have some odd problem with resizing bitmaps using GDI+.

Say i have an jpeg image 10000x5000. I display it's current part in original size with this:

graphics->DrawImage(bitmap, -x, -y, bitmap->GetWidth(), bitmap->GetHeight());


where x,y are coordinates of current shifting.

I'm resizing image like this:

Bitmap* newBitmap = new Bitmap((INT)(bitmap->GetWidth()*Scale), (INT)(bitmap->GetHeight()*Scale));
Graphics* graphics = new Graphics(newBitmap);
graphics->ScaleTransform(Scale, Scale);
graphics->DrawImage(bitmap, (INT)0, (INT)0, (INT)(bitmap->GetWidth()), (INT)(bitmap->GetHeight()));


And now the problem:
When I'm loading image direct from file, displaying works very fast, nice and without delays. But when i display resized image, even if it became smaller, drawing operation takes a lot more time then it was.

I have tried setting different InterpolationMode, SmoothingMode, PixelOffsetMode but it had no effect. I'm trying to manage with this problem for a long time. Tried different ways, but all they had no effect. Maybe I'm missing something obvious? Maybe some information from "file bitmap" gets lost? Pixel format is always the same. Well, now I don't have any other ideas, so I hope someone can help me with my issue.

Forgot to say that I'm using plain winapi, so .NET solution can't help me.
Posted
Updated 7-Jan-10 8:27am
v2

Maybe you could try using the original image and calling TranslateTransform(). The code would look something like this (Warning: not tested):
float width = bitmap->GetWidth()* Scale;
float height = bitmap->GetHeight()* Scale;
 
Graphics* graphics = new Graphics(bitmap);
graphics->TranslateTransform(width , height); 
graphics->ScaleTransform(Scale, Scale);
graphics->DrawImage(bitmap, (INT)0, (INT)0, (INT)width, (INT)height);
 
Share this answer
 
v2
Comments
Sergey Alexandrovich Kryukov 7-Oct-11 12:41pm    
Fixed formatting of HTML entities to render ->.
--SA
Two things:

1 - the framework ALWAYS creates a Bitmap, even if you ask for an Image instance. At least, it does in .NET.

2 - If your core issue is one of speed, the only possible explanation I can see is that you're leaking memory. The GDI+ system does NOT make copies that are somehow magically marked to make them slower to use. Have you tried writing code to resize an image and save the resized image, then just loading that ? I can see how a scale transform is an extra layer that has to be applied, which will slow it down, but if you actually resize the image, that should make no difference at all, so long as you're not generally slowing things down through a memory leak of significant proportions.
 
Share this answer
 
Is using a PictureBox control out of the question? Because you can set the Image property equal to the Bitmap and set the PictureBox's SizeMode property to PictureBoxSizeMode.Zoom. Then you can just resize the PictureBox and the Bitmap will automatically resize and maintain its aspect ratio. Double buffering should take care of any jerkiness during resizing.

My bad. I saw GDI+ and assumed Winforms.
 
Share this answer
 
v2
>>Maybe you could try using the original image and calling TranslateTransform()

I tried your suggestion. It didn't work. Tried something similar to that code, but all was futile. And also is seems that you can't draw image itself that way. Had to make another Bitmap to make it work somehow.
The main problem is that I have no idea how to change size of Bitmap from file. If it could be possible, then all would be much simpler.

Also even if I just draw another Bitmap on original Image, drawing operations again work slow.
 
Share this answer
 
v2
Maybe Image::GetThumbnailImage http://msdn.microsoft.com/en-us/library/ms535394(VS.85).aspx[^] will help.
 
Share this answer
 
Image::GetThumbnailImage is used for retrieving Thumbnail-image as it says. It can't give image more then certain resolution. So it is also no help.
 
Share this answer
 
I found another example here[^]. This may help you, although it looks very similar to your solution:
Draw in a Graphics object associated with a new Bitmap: 
class BitmapEx : public Bitmap 
{
public:
inline Bitmap* StretchClone(INT nWidth, INT nHeight);
public:
virtual ~BitmapEx();
};
inline Bitmap* BitmapEx::StretchClone(INT nWidth, INT nHeight)
{
Bitmap* pBitmap = new Bitmap(nWidth, nHeight); 
Graphics graphics(pBitmap);
graphics.DrawImage(this, 0, 0, nWidth, nHeight);
return pBitmap;
}
// Somewhere in space...
// Create a "stretched clone"
Bitmap* pBitmap = m_pBitmap->StretchClone(nWidth, nHeight);
// Save clone to file...
 
Share this answer
 
I used this method for creating resized image in the past. It does not work as well =(.
 
Share this answer
 
Have you tried using the Image class instead of the Bitmap class? You may be adding uneeded overhead by converting a jpg to a bitmap and then resizing it.

[Edit]

I mean replacing all instances of Bitmap with Image, not just in the resize step.
 
Share this answer
 
v2
Tried it just now. No effect at all.

upd:
Back then I tried all possible options.
 
Share this answer
 
v2
Thanks Christian Graus)
I really didn't try to save file. Just thought that it is something abnormal to do, though knew it could help in my issue and so it did.
I still can't figure out what the problem. I don't see any difference between bitmap, loaded from file and a bitmap that was created in memory. Though GDI+ sees this difference distinctly.
It is also no memory leak issue, because this problem acquires with not that big images as well. Above all speed decreasing appears even when I rotate image by Image::RotateFlip.
Can't think out why it could be that way.
 
Share this answer
 
I'm using plain winapi, so mfc and .net solutions can't help.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900