user302823
user302823

Reputation: 361

Resize with minimal loss of quality

I need to resize an image, but the image quality cannot be affected by this, the images will be from like 10x10 to 1000x1000, it will have some major congestions and some empty times it has to scale both up and down "potentially losing some image quality." is OK but it has to be at minimum, everything with raster graphics indeed NO libraries or other external binaries please

Upvotes: 2

Views: 1235

Answers (3)

Rick Strahl
Rick Strahl

Reputation: 17671

Whenever you resize images you're going to have some loss of quality - there's no way around that, but you can help minimize it by using the highest quality options in for the graphics context.

Here's what I use using plain GDI+ functions:

public static Bitmap ResizeImage(Bitmap bmp, int width, int height, 
                                 InterpolationMode mode = InterpolationMode.HighQualityBicubic)                                         
{
    Bitmap bmpOut = null;

    try
    {                                
        decimal ratio;
        int newWidth = 0;
        int newHeight = 0;

        // If the image is smaller than a thumbnail just return original size
        if (bmp.Width < width && bmp.Height < height)
        {
            newWidth = bmp.Width;
            newHeight = bmp.Height;
        }
        else
        {
            if (bmp.Width == bmp.Height)
            {
                if (height > width)
                {
                    newHeight = height;
                    newWidth = height;
                }
                else
                {
                    newHeight = width;
                    newWidth = width;                         
                }
            }
            else if (bmp.Width >= bmp.Height)
            {
                ratio = (decimal) width/bmp.Width;
                newWidth = width;
                decimal lnTemp = bmp.Height*ratio;
                newHeight = (int) lnTemp;
            }
            else
            {
                ratio = (decimal) height/bmp.Height;
                newHeight = height;
                decimal lnTemp = bmp.Width*ratio;
                newWidth = (int) lnTemp;
            }
        }

        //bmpOut = new Bitmap(bmp, new Size( newWidth, newHeight));                     
        bmpOut = new Bitmap(newWidth, newHeight);                
        bmpOut.SetResolution(bmp.HorizontalResolution, bmp.VerticalResolution);

        Graphics g = Graphics.FromImage(bmpOut);
        g.InterpolationMode = mode;

        g.SmoothingMode = SmoothingMode.HighQuality;
        g.PixelOffsetMode = PixelOffsetMode.HighQuality;

        g.FillRectangle(Brushes.White, 0, 0, newWidth, newHeight);
        g.DrawImage(bmp, 0, 0, newWidth, newHeight);                
    }
    catch
    {
        return null;
    }

    return bmpOut;
}

This resizes an image to the largest of either the width or the height - you can vary that algorithm to fit your resizing needs.

If you want to work with files you can add another helper that wraps the code above:

public static bool ResizeImage(string filename, string outputFilename, 
                                int width, int height, 
                                InterpolationMode mode = InterpolationMode.HighQualityBicubic)
{

    using (var bmpOut = ResizeImage(filename, width, height, mode) )
    {
        var imageFormat = GetImageFormatFromFilename(filename);
        if (imageFormat == ImageFormat.Emf)
            imageFormat = bmpOut.RawFormat; 

        bmpOut.Save(outputFilename, imageFormat);
    }

    return true;
}

GDI+ in general is not the best solution for high quality image manipulation - it's decent but if you need the highest quality, better performance and thread safety in Web apps you need to look at other options.

Bertrand LeRoy had a great article on Image Resizing some time ago that offers some alternatives using core .NET frameworks. http://weblogs.asp.net/bleroy/state-of-net-image-resizing-how-does-imageresizer-do

Upvotes: 0

Robert Fraser
Robert Fraser

Reputation: 10927

What you need is for your images to be scalable. I'd recommend using an XML format to store your images, since XML is very scalable. For example:

<Image Width="640" Height="480">
  <Pixel X="0" Y="0">
    <Red>20</Red>
    <Green>80</Green>
    <Blue>0</Blue>
    <Alpha>255</Alpha>
  </Pixel>
  <Pixel X="1" Y="0">
    ...

If you're worried about memory, I bet this will compress really well :-).

Upvotes: -2

kemiller2002
kemiller2002

Reputation: 115538

Here is a link showing you how to resize an image:

http://snippets.dzone.com/posts/show/4336

Upvotes: 4

Related Questions