Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / Languages / C# / March 2008

Tip: Looking for answers? Try searching our database.

Image Resizing.

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
tshad - 24 Mar 2008 23:50 GMT
I have a class I created to resize images in my program.

It seems to work pretty good with JPGs and GIFs.  Pngs look pretty good
until you try to expand them, such as in Micorsoft Office Picture Manager by
holding down the ctrl key and rolling your mouse wheel.  It expands fine and
you can see the picture but not the detail.  The letters start to blur.  If
you do the same thing with the original PNG file, it looks great as you
increase it.

How can I handle compression with a PNG file?

Here is my code:
***************************************************************
public static Image GetImageResize(Image oImage, int width)

{

int imageHeight;

int imageWidth;

float imageRatio;

// string s = System.Text.Encoding.ASCII.GetString(arrBytes);

imageRatio = (float)oImage.Height / (float)oImage.Width;

imageHeight = (int)(width * imageRatio);

imageWidth = width;

oImage = oImage.GetThumbnailImage(imageWidth, imageHeight, null,
IntPtr.Zero);

return oImage;

}

***************************************************************

Thanks,

Tom
Peter Duniho - 25 Mar 2008 00:18 GMT
> I have a class I created to resize images in my program.
>
> It seems to work pretty good with JPGs and GIFs.  Pngs look pretty good
> until you try to expand them, such as in Micorsoft Office Picture  
> Manager by
> holding down the ctrl key and rolling your mouse wheel. [...]

You haven't provided enough detail as to the nature of the images you're  
using for anyone to know for sure what's going on.

However, I suspect that the fundamental issue is that you're using a  
method intended for generating thumbnails as a general-purpose resizing  
technique.  The docs for GetThumbnailImage() specifically warn against  
this, and I suspect that what's happening is that your PNG files have an  
embedded thumbnail image or GetThumbnailImage() is otherwise able to  
obtain a pre-rendered thumbnail image that it then uses to generate the  
image of the specific size you ask for.

Since a thumbnail is going to necessarily have less detail than the  
original, any time this happens, the resized image is also going to have  
less detail.

You should be, just as the docs for GetThumbnailImage() indicate, be  
resizing the image directly.  You do this conveniently just by using the  
Image() constructor that takes an original image and a new size, or if you  
need higher-quality scaling, you can create a new Bitmap instance of the  
correct size and draw your original image into that Bitmap at the desired  
size, setting the Graphics settings as you desire (the InterpolationMode  
and SmoothingMode properties are the ones people usually want control over  
in this case).

Pete
tshad - 25 Mar 2008 19:33 GMT
>> I have a class I created to resize images in my program.
>>
[quoted text clipped - 17 lines]
> original, any time this happens, the resized image is also going to have
> less detail.

That makes sense.

The size of the original image is very large so when I increase the size of
that file, it is already large so I don't lose any data.  But when I try to
increase the size of the compressed (resized image), I already have lost
detail so the increase size will lose more data.

> You should be, just as the docs for GetThumbnailImage() indicate, be
> resizing the image directly.

I am.

I get oImage:
System.Drawing.Image oImage = null;

oImage = oImage.GetThumbnailImage(imageWidth, imageHeight, null,

from doing:

MemoryStream ms = new MemoryStream(myByteArray, 0, myByteArray.Length);

ms.Write(myByteArray, 0, myByteArray.Length);

oImage = Image.FromStream(ms, true);

>You do this conveniently just by using the  Image() constructor that takes
>an original image and a new size,

Isn't that what I am doing?

>or if you  need higher-quality scaling, you can create a new Bitmap
>instance of the  correct size
> and draw your original image into that Bitmap at the desired  size,
> setting the Graphics settings as you desire (the InterpolationMode  and
> SmoothingMode properties are the ones people usually want control over  in
> this case).

How would I do that?

I also found that if I do the:

oImage = Image.FromStream(ms, true);

with a .pcx file, I get an error:

Parameter is not valid.

Not sure why, but I just don't compress that file.

Thanks,

Tom

> Pete
Peter Duniho - 25 Mar 2008 20:07 GMT
> [...]
>> You should be, just as the docs for GetThumbnailImage() indicate, be
>> resizing the image directly.
>
> I am.

I don't think you are.  By "directly" I mean that you shouldn't be using  
GetThumbnailImage() at all.

> [...]
>> You do this conveniently just by using the  Image() constructor that  
>> takes
>> an original image and a new size,
>
> Isn't that what I am doing?

I haven't seen any code in this thread that uses an Bitmap() constructor  
explicitly (sorry...I should have stated "Bitmap" instead of "Image"...the  
Image class is abstract and has no constructors of course).  For example:

    Image GetImageResize(Image image, int cxWidth, int cyHeight)
    {
        return new Bitmap(image, cxWidth, cyHeight);
    }

>> or if you  need higher-quality scaling, you can create a new Bitmap
>> instance of the  correct size
[quoted text clipped - 5 lines]
>
> How would I do that?

For example:

    Image GetImageResize(Image image, int cxWidth, int cyHeight)
    {
        Image imageRet = new Bitmap(cxWidth, cyHeight);

        using (Graphics gfx = Graphics.FromImage(imageRet))
        {
            gfx.DrawImage(image, 0, 0, cxWidth, cyHeight);
        }

        return imageRet;
    }

Adding, of course, whatever specific drawing settings you want in order to  
control the quality of the redrawn image.

> I also found that if I do the:
>
[quoted text clipped - 5 lines]
>
> Not sure why, but I just don't compress that file.

Well, according to the docs for the Bitmap class, .NET/GDI+ doesn't  
support PCX.  It lists BMP, GIF, EXIG, JPG, PNG and TIFF.  No PCX.

Pete
tshad - 25 Mar 2008 21:00 GMT
>> [...]
>>> You should be, just as the docs for GetThumbnailImage() indicate, be
[quoted text clipped - 9 lines]
>>> takes
>>> an original image and a new size,

Isn't that the same thing as the GetThumbnailImage() where you take the
Image and GetThumbnailImage resizes it to the size you pass:
   MemoryStream ms = new MemoryStream(myByteArray, 0, myByteArray.Length);
   ms.Write(myByteArray, 0, myByteArray.Length);
   System.Drawing.Image oImage = Image.FromStream(ms, true);
  oImage = oImage.GetThumbnailImage(imageWidth, imageHeight, null,
IntPtr.Zero);

as opposed to your GetImageResize:

   MemoryStream ms = new MemoryStream(myByteArray, 0, myByteArray.Length);
   ms.Write(myByteArray, 0, myByteArray.Length);
   System.Drawing.Image oImage = Image.FromStream(ms, true);
  oImage = GetImageResize(Image image, imageWidth, imageHeight;

I would assume (though I am probably wrong here) that the Bitmap resize is
doing the same thing as the GetThumbnailImage.

>> Isn't that what I am doing?
>
[quoted text clipped - 6 lines]
>          return new Bitmap(image, cxWidth, cyHeight);
>      }

But a BitMap takes more space that say a jpeg.

What we are trying to do is take a 1 meg jpeg file and compress (may be the
wrong word here) it a to a newer size based on the width.  Using
GetThumbnailImage we get a new jpeg to about 50k.

>>> or if you  need higher-quality scaling, you can create a new Bitmap
>>> instance of the  correct size
[quoted text clipped - 19 lines]
>          return imageRet;
>      }

I assume you meant:

      Image imageRet = new Bitmap(image,cxWidth, cyHeight);

> Adding, of course, whatever specific drawing settings you want in
> order to control the quality of the redrawn image.
[quoted text clipped - 11 lines]
> Well, according to the docs for the Bitmap class, .NET/GDI+ doesn't
> support PCX.  It lists BMP, GIF, EXIG, JPG, PNG and TIFF.  No PCX.

And you explained that the Image class is really an abstract class and I
assume is derived from the Bitmap class which would explain why it doesn't
work.

Thanks,

Tom

> Pete
Peter Duniho - 25 Mar 2008 21:17 GMT
> [...]
> I would assume (though I am probably wrong here) that the Bitmap resize  
> is
> doing the same thing as the GetThumbnailImage.

I'm not sure what to say.  You acknowledge you made an assumption _and_  
that you're probably wrong, and yet you are still wondering why my code is  
different from yours?

The method GetThumbnailImage() has a very specific purpose: to retrieve a  
thumbnail image.  Some images come with thumbnails already created, and if  
they do, that's the image that will be used.  You can optionally request  
that the thumbnail be returned as a specific size, but when you do so, you  
are asking for the _thumbnail_ to be resized, not the original image.

If an image does not yet have a thumbnail, then yes...the original is used  
instead.  But otherwise, it's not.

The code I provided resizes the original image _always_.  If you don't  
want to accidently resize the thumbnail instead of the original image,  
don't use GetThumbnailImage().

> But a BitMap takes more space that say a jpeg.

Not in memory it doesn't.  JPEG is a format used mainly for files.  In  
.NET, when you read a JPEG file, you get an uncompressed Bitmap in memory.

> What we are trying to do is take a 1 meg jpeg file and compress (may be  
> the
> wrong word here) it a to a newer size based on the width.  Using
> GetThumbnailImage we get a new jpeg to about 50k.

And so too can you with the Bitmap.  Just save the Bitmap instance in the  
JPEG format.

> [...]
> I assume you meant:
>
>        Image imageRet = new Bitmap(image,cxWidth, cyHeight);

That's an incorrect assumption.

>> Well, according to the docs for the Bitmap class, .NET/GDI+ doesn't
>> support PCX.  It lists BMP, GIF, EXIG, JPG, PNG and TIFF.  No PCX.
[quoted text clipped - 3 lines]
> doesn't
> work.

No.  Bitmap inherits Image, not the other way around.  And in either case  
that has nothing to do with why a PCX file isn't supported.

Pete

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.