Bibliothèque de mise à l’échelle d’image de haute qualité

Je veux mettre à l’échelle une image en C # avec un niveau de qualité aussi bon que celui de Photoshop. Y a-t-il une bibliothèque de traitement d’image C # disponible pour faire cela?

Voici une classe d’assistance de manipulation d’images bien commentée que vous pouvez consulter et utiliser. Je l’ai écrit comme exemple sur la façon d’effectuer certaines tâches de manipulation d’image en C #. Vous serez intéressé par la fonction ResizeImage qui prend System.Drawing.Image, la largeur et la hauteur comme arguments.

using System; using System.Collections.Generic; using System.Drawing; using System.Drawing.Imaging; namespace DoctaJonez.Drawing.Imaging { ///  /// Provides various image untilities, such as high quality resizing and the ability to save a JPEG. ///  public static class ImageUtilities { ///  /// A quick lookup for getting image encoders ///  private static Dictionary encoders = null; ///  /// A lock to prevent concurrency issues loading the encoders. ///  private static object encodersLock = new object(); ///  /// A quick lookup for getting image encoders ///  public static Dictionary Encoders { //get accessor that creates the dictionary on demand get { //if the quick lookup isn't initialised, initialise it if (encoders == null) { //protect against concurrency issues lock (encodersLock) { //check again, we might not have been the first person to acquire the lock (see the double checked lock pattern) if (encoders == null) { encoders = new Dictionary(); //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; } } ///  /// Resize the image to the specified width and height. ///  /// The image to resize. /// The width to resize to. /// The height to resize to. /// The resized image. 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); //set the resolutions the same to avoid cropping due to resolution differences result.SetResolution(image.HorizontalResolution, image.VerticalResolution); //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; } ///  /// Saves an image as a jpeg image, with the given quality ///  /// Path to which the image would be saved. /// An integer from 0 to 100, with 100 being the /// highest quality ///  /// An invalid value was entered for image quality. ///  public static void SaveJpeg(ssortingng path, Image image, int quality) { //ensure the quality is within the correct range if ((quality < 0) || (quality > 100)) { //create the error message ssortingng error = ssortingng.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); } ///  /// Returns the image codec with the given mime type ///  public static ImageCodecInfo GetEncoderInfo(ssortingng mimeType) { //do a case insensitive search for the mime type ssortingng 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; } } } 

Mettre à jour

Quelques personnes ont demandé dans les commentaires des exemples d’utilisation de la classe ImageUtilities, alors voilà.

 //resize the image to the specified height and width using (var resized = ImageUtilities.ResizeImage(image, 50, 100)) { //save the resized image as a jpeg with a quality of 90 ImageUtilities.SaveJpeg(@"C:\myimage.jpeg", resized, 90); } 

Remarque

Rappelez-vous que les images sont jetables, vous devez donc affecter le résultat de votre redimensionnement à une déclaration d’utilisation (ou vous pouvez enfin essayer et vous assurer que vous appelez disposer dans votre enfin).

Lorsque vous dessinez l’image en utilisant GDI +, elle évolue assez bien selon moi. Vous pouvez l’utiliser pour créer une image mise à l’échelle.

Si vous voulez redimensionner votre image avec GDI +, vous pouvez faire quelque chose comme ceci:

 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)); } 

Des bibliothèques testées comme Imagemagick et GD sont disponibles pour .NET

Vous pouvez également lire des choses comme l’interpolation bicubique et écrire les vôtres.

Articles CodeProject abordant et partageant le code source pour la mise à l’ échelle des images:

  • Mise à l’échelle en deux passes à l’aide de filtres
  • Transformation masortingcielle des images en C #, en utilisant .NET GDI +
  • Redimensionnement d’une image photographique avec GDI + pour .NET
  • Mise à l’échelle rapide de l’image dyadique avec la transformation de Haar

Utilisez cette bibliothèque: http://imageresizing.net

Lisez cet article de l’auteur de la bibliothèque: 20 pièges à taille d’image avec .NET

Essayez les différentes valeurs pour Graphics.InterpolationMode. Plusieurs algorithmes de mise à l’échelle sont disponibles dans GDI +. Si l’un d’entre eux est suffisant pour votre besoin, vous pouvez suivre cette route au lieu de vous fier à une bibliothèque externe.

Vous pouvez essayer dotImage , l’un des produits de mon entreprise, qui inclut un object de rééchantillonnage d’ images comportant 18 types de filtres pour différents niveaux de qualité.

L’utilisation typique est:

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

De plus, dotImage comprend 140 commandes de traitement d’images bizarres, dont de nombreux filtres similaires à ceux de PhotoShop, si c’est ce que vous recherchez.

Cela pourrait aider

  public Image ResizeImage(Image source, RectangleF destinationBounds) { RectangleF sourceBounds = new RectangleF(0.0f,0.0f,(float)source.Width, (float)source.Height); RectangleF scaleBounds = new RectangleF(); Image destinationImage = new Bitmap((int)destinationBounds.Width, (int)destinationBounds.Height); Graphics graph = Graphics.FromImage(destinationImage); graph.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; // Fill with background color graph.FillRectangle(new SolidBrush(System.Drawing.Color.White), destinationBounds); float resizeRatio, sourceRatio; float scaleWidth, scaleHeight; sourceRatio = (float)source.Width / (float)source.Height; if (sourceRatio >= 1.0f) { //landscape resizeRatio = destinationBounds.Width / sourceBounds.Width; scaleWidth = destinationBounds.Width; scaleHeight = sourceBounds.Height * resizeRatio; float sortingmValue = destinationBounds.Height - scaleHeight; graph.DrawImage(source, 0, (sortingmValue / 2), destinationBounds.Width, scaleHeight); } else { //portrait resizeRatio = destinationBounds.Height/sourceBounds.Height; scaleWidth = sourceBounds.Width * resizeRatio; scaleHeight = destinationBounds.Height; float sortingmValue = destinationBounds.Width - scaleWidth; graph.DrawImage(source, (sortingmValue / 2), 0, scaleWidth, destinationBounds.Height); } return destinationImage; } 

Notez l’ InterpolationMode.HighQualityBicubic -> c’est généralement un bon compromis entre les performances et les résultats.

Essayez cet extrait de code de base:

 private static Bitmap ResizeBitmap(Bitmap srcbmp, int width, int height ) { Bitmap newimage = new Bitmap(width, height); using (Graphics g = Graphics.FromImage(newimage)) g.DrawImage(srcbmp, 0, 0, width, height); return newimage; } 

Il y a un article sur Code Project concernant l’utilisation de GDI + pour .NET pour faire du redimensionnement de photos en utilisant, par exemple, l’interpolation bicubique.

Il y avait aussi un autre article sur ce sujet sur un autre blog (un employé de MS, je pense), mais je ne trouve le lien nulle part. 🙁 Peut-être que quelqu’un d’autre peut le trouver?

vous pouvez essayer celui-ci si c’est un filtre d’image 2D lowres cgi

Ceci est un article que j’ai repéré être référencé dans le code de Paint.NET pour le rééchantillonnage d’image: Diverses techniques simples de traitement d’image par Paul Bourke.

Vous pourriez essayer le kernel magique . Il produit moins d’artefacts de pixellisation que le ré-échantillonnage bicubique lors de la mise à l’échelle et il donne également de très bons résultats lors de la réduction d’échelle. Le code source est disponible dans c # à partir du site Web.

J’ai quelques améliorations pour la réponse du docteur Jones.

Cela fonctionne pour qui voulait comment redimensionner l’image proportionnellement. Il a testé et travaillé pour moi.

Les méthodes de classe I ont ajouté:

 public static System.Drawing.Bitmap ResizeImage(System.Drawing.Image image, Size size) { return ResizeImage(image, size.Width, size.Height); } public static Size GetProportionedSize(Image image, int maxWidth, int maxHeight, bool withProportion) { if (withProportion) { double sourceWidth = image.Width; double sourceHeight = image.Height; if (sourceWidth < maxWidth && sourceHeight < maxHeight) { maxWidth = (int)sourceWidth; maxHeight = (int)sourceHeight; } else { double aspect = sourceHeight / sourceWidth; if (sourceWidth < sourceHeight) { maxWidth = Convert.ToInt32(Math.Round((maxHeight / aspect), 0)); } else { maxHeight = Convert.ToInt32(Math.Round((maxWidth * aspect), 0)); } } } return new Size(maxWidth, maxHeight); } 

et nouveau disponible en utilisant selon ces codes:

 using (var resized = ImageUtilities.ResizeImage(image, ImageUtilities.GetProportionedSize(image, 50, 100))) { ImageUtilities.SaveJpeg(@"C:\myimage.jpeg", resized, 90); }