How to reduce image file size?

G

Guest

Is there any routine I can call to reduce the size of an image file after
uploading a file from a client. I am looking to reduce file sizes
programmatically using C# in my web page after uploading. I know that
Photoshop can do it but I need to do it dynamically in my web page. I tried
doing it myself with some of the Bitmap thumbnail instructions but the
resulting image is very bad. I need a file reduction routine that creates a
good image that is smaller. I figured if Photoshop can do it then so can I
but how?
 
G

Guest

Brock;
Thanks for yur reply. I tried the Get ThumbnailImage function but the
resulting image is fuzzy. I reduced a 1360 X 2048 image to 272 X 408 and the
edges are blurry. I need something that gives me a better resolution.
 
F

Fred Exley

Parrot said:
Brock;
Thanks for yur reply. I tried the Get ThumbnailImage function but the
resulting image is fuzzy. I reduced a 1360 X 2048 image to 272 X 408 and
the
edges are blurry. I need something that gives me a better resolution.



My first trys using GetThumbnailImage were very ugly, but this makes images
that look just fine:
-Fred


using System;

using System.Data;

using System.Configuration;

using System.Web;

using System.Web.Security;

using System.Web.UI;

using System.Web.UI.WebControls;

using System.Web.UI.WebControls.WebParts;

using System.Web.UI.HtmlControls;

using System.IO;

using System.Drawing;



/// <summary>

/// Summary description for makeThumbnail

/// </summary>

public class makeThumbnail

{

public makeThumbnail(string parmFileIn, out int rc)

{

rc = 0;

string filePathSourceFile = HttpContext.Current.Server.MapPath("~/images/");

string filePathDestFile =
HttpContext.Current.Server.MapPath("~/thumbnails/");

string fullSourceFile = filePathSourceFile + parmFileIn;

//string currentImageFile;

//string thumbnailFile;

int thumbnailHeight;

int thumbnailWidth;

int maxThumbSize = 150;

//int minThumbSize = 120; // 4 x 6 ratio

double hx; double wx;

// create an image object, using the filename we just retrieved

System.Drawing.Image sourceImage =
System.Drawing.Image.FromFile(fullSourceFile);

hx = sourceImage.Height;

wx = sourceImage.Width;

// calc the thumbnail Width and Height: -scale to max with

if (sourceImage.Width > sourceImage.Height) // landscape: width is fixed,
scale height:

{

thumbnailWidth = maxThumbSize;

//thumbnailHeight = minThumbSize;

thumbnailHeight = Convert.ToInt32((hx / wx) * thumbnailWidth);

}

else // portrait: height is fixed at max, scale width:

{

thumbnailHeight = maxThumbSize;

thumbnailWidth = Convert.ToInt32((wx / hx) * thumbnailHeight);

}

System.Drawing.Image thumbnailImage =
sourceImage.GetThumbnailImage(thumbnailWidth, thumbnailHeight, new
System.Drawing.Image.GetThumbnailImageAbort(ThumbnailCallback),
IntPtr.Zero);


// make a memory stream to work with the image bytes

MemoryStream imageStream = new MemoryStream();

// put the image into the memory stream

thumbnailImage.Save(imageStream, System.Drawing.Imaging.ImageFormat.Jpeg);

string outfile = filePathDestFile + parmFileIn;

try

{

thumbnailImage.Save(outfile);

rc = 77;

}

catch (Exception e)

{

rc = 27;

string dummy = e.ToString();

return;

}

}

/// <summary>

/// </summary>

/// <returns>true</returns>

public bool ThumbnailCallback()

{

return true;

}


}
 
G

Guest

Fred;
Thanks for your reply. I copied your coding and ran a test and it gave
similar results from my code in that any thumbnail having a size greater than
40K bytes shows a marked deterioration in quality. I guess since it is a
thumbnail routine, it is advisable to keep the resulting image at a thumbnail
size rather than just a reduction from the original image.
Dave Uphoff
 
G

Guest

Actually, GetThumbNailImage is not the best solution at all. Here's a
ResizeImage method for a control I developed a year or so ago in Whidbey
beta. I have compiled it in the release version but haven't tested it. In
either case, it will show you how to use a Graphics object to resize your
image while maintaining high quality.
 
G

Guest

Whoops. Here's the code:

private Image ResizeImage(Image mg, Size newSize)
{
double ratio = 0d;
double myThumbWidth = 0d;
double myThumbHeight = 0d;
int x = 0;
int y = 0;

Bitmap bp;

if ((mg.Width / Convert.ToDouble(newSize.Width)) > (mg.Height /
Convert.ToDouble(newSize.Height)))
ratio = Convert.ToDouble(mg.Width) / Convert.ToDouble(newSize.Width);
else
ratio = Convert.ToDouble(mg.Height) / Convert.ToDouble(newSize.Height);
myThumbHeight = Math.Ceiling(mg.Height / ratio);
myThumbWidth = Math.Ceiling(mg.Width / ratio);


Size thumbSize = new Size((int)myThumbWidth, (int)myThumbHeight);
bp = new Bitmap(newSize.Width, newSize.Height);
x = (newSize.Width - thumbSize.Width) / 2;
y = (newSize.Height - thumbSize.Height);

Graphics g = Graphics.FromImage(bp);
g.SmoothingMode = SmoothingMode.HighQuality;
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.PixelOffsetMode = PixelOffsetMode.HighQuality;
Rectangle rect = new Rectangle(x, y, thumbSize.Width, thumbSize.Height);
g.DrawImage(mg, rect, 0, 0, mg.Width, mg.Height, GraphicsUnit.Pixel);
return bp;
}
 
G

Guest

Dale;
Thank you for your reply. Can this code only work in ASPNET 2.0? I get
compile errors trying it in 1.1 because it doesn't recognize the Graphics
class for Web forms and I don't know what the Namespace is?
Dave Uphoff
 
G

Guest

Dale;
Just to let you know that I got your routine to work and it does create a
sharp image even though the file size is reduced. I want to thank you very
much for giving me a valuable tool for web programming. I did have to make
some changes to make it work in ASPNET 1.1. I needed to add the Namespace
System.Drawing.Drawing2D. I also made a few other changes to make it work
for me which I have highlighted in the code below. The routine reduced a
650KB image file to a 14.7 KB file with 250 X 400 dimension and the clarity
is intact just like in Photoshop. Thanks again.
Dave Uphoff

Here is the calling routine:

Bitmap mg = new Bitmap("c:\\scanpics\\animals\\cats\\midnite1.jpg");

Size newSize = new Size(250, 400);

Bitmap bp = ResizeImage(mg, newSize);

bp.Save("c:\\inetpub\\wwwroot\\warmfrag\\pics\\myimage.jpg",System.Drawing.Imaging.ImageFormat.Jpeg);
--------------------------------------------------------------------

And here is the routine itself.
------------------------------------------------------------------

private Bitmap ResizeImage(Bitmap mg, Size newSize)
{
double ratio = 0d;
double myThumbWidth = 0d;
double myThumbHeight = 0d;
int x = 0;
int y = 0;

Bitmap bp;


if ((mg.Width / Convert.ToDouble(newSize.Width)) > (mg.Height /
Convert.ToDouble(newSize.Height)))
ratio = Convert.ToDouble(mg.Width) / Convert.ToDouble(newSize.Width);
else
ratio = Convert.ToDouble(mg.Height) / Convert.ToDouble(newSize.Height);
myThumbHeight = Math.Ceiling(mg.Height / ratio);
myThumbWidth = Math.Ceiling(mg.Width / ratio);

Size thumbSize = new Size((int)myThumbWidth, (int)myThumbHeight);
bp = new Bitmap(newSize.Width, newSize.Height);
x = (newSize.Width - thumbSize.Width) / 2;
y = (newSize.Height - thumbSize.Height);
// Had to add System.Drawing class in front of Graphics ---
System.Drawing.Graphics g = Graphics.FromImage(bp);
g.SmoothingMode = SmoothingMode.HighQuality;
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.PixelOffsetMode = PixelOffsetMode.HighQuality;
Rectangle rect = new Rectangle(x, y, thumbSize.Width, thumbSize.Height);
g.DrawImage(mg, rect, 0, 0, mg.Width, mg.Height, GraphicsUnit.Pixel);

return bp;


}
 
F

Fred Exley

Sounds like you guys have the better way. But I can't get either one to
compile -in particular it errors on 'Size'. What namespaces are you
including? thanks -Fred
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top