views:

15541

answers:

9

I want to scale an image in C# with quality level as good as Photoshop does. Is there any C# image processing library available to do this thing?

+6  A: 

When you draw the image using GDI+ it scales quite well in my opinion. You can use this to create a scaled image.

If you want to scale your image with GDI+ you can do something like this:

Bitmap original = ...
Bitmap scaled = new Bitmap(new Size(original.Width * 4, original.Height * 4));
using (Graphics graphics = Graphics.FromImage(scaled)) {
  graphics.DrawImage(original, new Rectangle(0, 0, scaled.Width, scaled.Height));
}
Hallgrim
+7  A: 

Tested libraries like Imagemagick and GD are available for .NET

You could also read up on things like bicubic interpolation and write your own.

kitsune
+3  A: 

Try the different values for Graphics.InterpolationMode. There are several typical scaling algorithms available in GDI+. If one of these is sufficient for your need, you can go this route instead of relying on an external library.

OregonGhost
A: 

There's an article on Code Project about using GDI+ for .NET to do photo resizing using, say, Bicubic interpolation.

There was also another article about this topic on another blog (MS employee, I think), but I can't find the link anywhere. :( Perhaps someone else can find it?

+1  A: 

You can try dotImage, one of my company's products, which includes an object for resampling images that has 18 filter types for various levels of quality.

Typical usage is:

// BiCubic is one technique available in PhotoShop
ResampleCommand resampler = new ResampleCommand(newSize, ResampleMethod.BiCubic);
AtalaImage newImage = resampler.Apply(oldImage).Image;

in addition, dotImage includes 140 some odd image processing commands including many filters similar to those in PhotoShop, if that's what you're looking for.

plinth
The SDK with this feature is now available for free for common photo formats (JPEG, PNG, etc) http://www.atalasoft.com/photofree
Lou Franco
+30  A: 

Here's a nicely commented Image Manipulation helper class that you can look at and use. I wrote it as an example of how to perform certain image manipulation tasks in C#. You'll be interested in the ResizeImage function that takes a System.Drawing.Image, the width and the height as the arguments.

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;

namespace DoctaJonez.Drawing.Imaging
{
    /// <summary>
    /// Provides various image untilities, such as high quality resizing and the ability to save a JPEG.
    /// </summary>
    public static class ImageUtilities
    {    
        /// <summary>
        /// A quick lookup for getting image encoders
        /// </summary>
        private static Dictionary<string, ImageCodecInfo> encoders = null;

        /// <summary>
        /// A quick lookup for getting image encoders
        /// </summary>
        public static Dictionary<string, ImageCodecInfo> Encoders
        {
            //get accessor that creates the dictionary on demand
            get
            {
                //if the quick lookup isn't initialised, initialise it
                if (encoders == null)
                {
                    encoders = new Dictionary<string, ImageCodecInfo>();
                }

                //if there are no codecs, try loading them
                if (encoders.Count == 0)
                {
                    //get all the codecs
                    foreach (ImageCodecInfo codec in ImageCodecInfo.GetImageEncoders())
                    {
                        //add each codec to the quick lookup
                        encoders.Add(codec.MimeType.ToLower(), codec);
                    }
                }

                //return the lookup
                return encoders;
            }
        }

        /// <summary>
        /// Resize the image to the specified width and height.
        /// </summary>
        /// <param name="image">The image to resize.</param>
        /// <param name="width">The width to resize to.</param>
        /// <param name="height">The height to resize to.</param>
        /// <returns>The resized image.</returns>
        public static System.Drawing.Bitmap ResizeImage(System.Drawing.Image image, int width, int height)
        {
            //a holder for the result
            Bitmap result = new Bitmap(width, height);

            //use a graphics object to draw the resized image into the bitmap
            using (Graphics graphics = Graphics.FromImage(result))
            {
                //set the resize quality modes to high quality
                graphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
                graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
                graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
                //draw the image into the target bitmap
                graphics.DrawImage(image, 0, 0, result.Width, result.Height);
            }

            //return the resulting bitmap
            return result;
        }

        /// <summary> 
        /// Saves an image as a jpeg image, with the given quality 
        /// </summary> 
        /// <param name="path">Path to which the image would be saved.</param> 
        /// <param name="quality">An integer from 0 to 100, with 100 being the 
        /// highest quality</param> 
        /// <exception cref="ArgumentOutOfRangeException">
        /// An invalid value was entered for image quality.
        /// </exception>
        public static void SaveJpeg(string path, Image image, int quality)
        {
            //ensure the quality is within the correct range
            if ((quality < 0) || (quality > 100))
            {
                //create the error message
                string error = string.Format("Jpeg image quality must be between 0 and 100, with 100 being the highest quality.  A value of {0} was specified.", quality);
                //throw a helpful exception
                throw new ArgumentOutOfRangeException(error);
            }

            //create an encoder parameter for the image quality
            EncoderParameter qualityParam = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, quality);
            //get the jpeg codec
            ImageCodecInfo jpegCodec = GetEncoderInfo("image/jpeg");

            //create a collection of all parameters that we will pass to the encoder
            EncoderParameters encoderParams = new EncoderParameters(1);
            //set the quality parameter for the codec
            encoderParams.Param[0] = qualityParam;
            //save the image using the codec and the parameters
            image.Save(path, jpegCodec, encoderParams);
        }

        /// <summary> 
        /// Returns the image codec with the given mime type 
        /// </summary> 
        public static ImageCodecInfo GetEncoderInfo(string mimeType)
        {
            //do a case insensitive search for the mime type
            string lookupKey = mimeType.ToLower();

            //the codec to return, default to null
            ImageCodecInfo foundCodec = null;

            //if we have the encoder, get it to return
            if (Encoders.ContainsKey(lookupKey))
            {
                //pull the codec from the lookup
                foundCodec = Encoders[lookupKey];
            }

            return foundCodec;
        } 
    }
}
DoctaJonez
ImageCodecInfo jpegCodec = getEncoderInfo("image/jpeg"); - where did you define getEncoderInfo cause I can't compile it
ile
It should read GetEncoderInfo and not getEncoderInfo. I fixed the typo and the class compiles now.
DoctaJonez
How to use this code to show thumbnail on fly (without saving thumbnail to a file)?
ile
Use the ResizeImage function, it returns the resized image as a System.Drawing.Bitmap object that you can use.
DoctaJonez
+1 this works brilliantly! One issue you need to correct in this code is to convert the quality variable to a long prior to passing it to the encoder param or you will get a invalid parameter runtime exception.
James
+1  A: 

This is an article I spotted being referenced in Paint.NET's code for image resampling: Various Simple Image Processing Techniques by Paul Bourke.

Igor Brejc
A: 

you could try this one if it's a lowres cgi 2D Image Filter

Cryx