Feedback

C# - Bilder proportional Skalieren

Veröffentlicht von am 11.12.2009
(3 Bewertungen)
Bertrand Le Roy hat in einem Blogartikel (http://bit.ly/6o4ziC) gezeigt, dass die Bildmanipulationen mit WPF bis zu 3x schneller arbeiten als die Funktionen aus dem Namensraum System.Drawing (GDI+). Auch die Dateigrößen sind geringer bei gleicher oder sogar besserer Bildqualität.

Der hier gezeigten Methode übergibt man zum einen den Stream mit dem Bild (bsp. aus den POST-Daten einer ASP.NET Anwendung), die gewünschte Maximalgröße (Breite und Höhe in Pixeln bei 92 DPI) und den zu verwendenden Algorithmus für die Neuberechnung. Hier empfiehlt sich eigentlich immer "BitmapScalingMode.HighQuality" bzw. "BitmapScalingMode.Fant" (beide gleichwertig, ersteres existiert noch aus Kompatibilitätsgründen).

Als Ergebnis bekommt man wieder einen Stream zurück, den man beispielsweise als Datei speichern kann.

Beispiel für ASP.NET MVC:

HttpPostedFileBase posted = Request.Files[file];
string fn = Guid.NewGuid() + ".png";
FileStream fs = System.IO.File.Create("~/upload/" + fn);
Resize(posted.InputStream, 100, 100, BitmapScalingMode.Fant).WriteTo(fs);
fs.Close();
posted.InputStream.Close();
GFU-Schulungen  [Anzeige]

C# 2017/2015/2013 Grundlagen

Nach Abschluss des Kurses sind Ihnen die Datentypen und Klassenbibliotheken von C# bekannt. Außerdem sind Sie in der Lage, mit Variablen umzugehen und deren Typen zu konvertieren. Sie definieren Namespaces und setzen diese ein, Sie erstellen eigene Klassen  und bauen Trouble Shooting ein.

VB.NET Einführung

Die Schulung zeigt Ihnen, wie Sie einfache, benutzerorientierte Programme, die auf Datenbanken zugreifen, in VB.NET eigenständig entwickeln. 

using System;
using System.IO;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Imaging;

public static class ImgScale {
  /// <summary>
  /// Resizes the specified image stream
  /// </summary>
  /// <param name="imageStream">The source image stream</param>
  /// <param name="maxWidth">maximum width of the scaled image</param>
  /// <param name="maxHeight">maximum height of the scaled image</param>
  /// <param name="scalingMode">rendering mode</param>
  /// <returns></returns>
  public static Stream Resize(Stream imageStream, int maxWidth, int maxHeight, BitmapScalingMode scalingMode) {
    // Lade den ersten (und meistens einzigen) Frame aus dem Stream der Bilddatei und gib den Algorithmus zum Neuberechnen vor
    BitmapDecoder imgDecoder = BitmapDecoder.Create(imageStream, BitmapCreateOptions.None, BitmapCacheOption.Default);
    BitmapFrame img = imgDecoder.Frames[0];
    DrawingGroup group = new DrawingGroup();
    RenderOptions.SetBitmapScalingMode(group, scalingMode);
    
    // Berechne die Verhältnisse des Originalbildes zur gewünschten Maximalgröße und bestimme so welche der beiden übergebenen
    // Werte übernommen, und welcher skaliert werden muss
    float xP = maxWidth / (float)img.Width;
    float yP = maxHeight / (float)img.Height;
    if (xP > yP)
      maxWidth = Convert.ToInt32(img.Width * yP);
    else
      maxHeight = Convert.ToInt32(img.Height * xP);


    // Lege eine neue Grafik mit den berechneten Maßen an und berechne das Originalbild neu
    group.Children.Add(new ImageDrawing(img, new Rect(0, 0, maxWidth, maxHeight)));
    DrawingVisual targetVisual = new DrawingVisual();
    DrawingContext targetContext = targetVisual.RenderOpen();
    targetContext.DrawDrawing(group);
    RenderTargetBitmap target = new RenderTargetBitmap(maxWidth, maxHeight, 96, 96, PixelFormats.Default); // 96 DPI, Standart-Bildschirmauflösung
    targetContext.Close();
    target.Render(targetVisual);
    BitmapFrame targetFrame = BitmapFrame.Create(target);
    
    // Der PNG-Encode bietet sich in den meisten Fällen an, da er die beste Qualität bietet
    // GIF hat gerade bei Fotos eine zu niedrige Farbanzahl und JPEG hat eine verlustbehaftete Bildkompression
    PngBitmapEncoder targetEncoder = new PngBitmapEncoder();
    
    targetEncoder.Frames.Add(targetFrame);
    Stream output = null;
    targetEncoder.Save(output);
    return output;
  }
}

Kommentare zum Snippet

 

Logge dich ein, um hier zu kommentieren!