System.Drawing in ASP.NET ASP.NET Core

Es gibt viele Fragen zur Verwendung der System.Drawing Bibliothek in ASP.NET-Diensten. Die häufigste Antwort ist, dass Microsoft die Verwendung von System.Drawing in ASP.NET-Diensten nicht empfiehlt.

In diesem Artikel erfahren Sie Details zur Verwendung der Schnittstelle der System.Drawing Bibliothek in ASP.NET-Diensten mit Aspose.Drawing for .NET. Die folgenden Abschnitte gliedern alle relevanten Informationen:

Warum Aspose.Drawing?

Microsoft empfiehlt die Verwendung seiner System.Drawing Bibliothek in ASP.NET-Diensten nicht. Die Homepage von System.Drawing Dokumentation lautet:

Klassen im System.Drawing-Namespace werden nicht für die Verwendung in einem Windows oder ASP.NET-Dienst unterstützt. Der Versuch, diese Klassen innerhalb eines dieser Anwendungstypen zu verwenden, kann zu Laufzeitausnahmen und einer verringerten Dienstleistung führen.

Es gibt zwei grundlegende Probleme, die Microsoft dazu zwingen, über Vorsicht zu schreiben. Das erste Problem ist die Verwendung der nativen GDI+ Bibliothek und folglich die Verwendung von GDI-Handles. Während die zweite Sorge Nebenläufigkeitsprobleme betrifft. Beispielsweise tritt während jeder DrawImage()-Operation eine prozessweite Sperre auf. Daher können Sie mit der System.Drawing Bibliothek von Microsoft keine schnellen und skalierbaren ASP.NET-Dienste erstellen.

Installieren von Aspose.Drawing for .NET API

Sie können die DLL Datei einfach aus dem Abschnitt Downloads herunterladen oder sie über den NuGet-Paket-Manager mit dem folgenden Befehl konfigurieren:

PM> Install-Package Aspose.Drawing

Aspose.Drawing for .NET API – Einführung

Wir verstehen, dass System.Drawing aufgrund seiner Bildbearbeitungsfunktionen bei Entwicklern sehr beliebt ist. Aus diesem Grund haben wir eine ähnliche und kompatible API ohne Kompatibilitätsprobleme erstellt. Für Ihre Bequemlichkeit und Anpassbarkeit enthält die API die gleichen Namen von Klassen, Funktionen, Aufzählungen und Schnittstellen. Sie können einfach die Projektreferenz von System.Drawing in Aspose.Drawing ändern und das Programm neu kompilieren.

Darüber hinaus ist Aspose.Drawing eine verwaltete Bibliothek, die für NET Framework 2.0 und NET Core 2.0 verfügbar ist. Im Gegensatz zu System.Drawing hat es keine Abhängigkeiten von Plattformen wie Linux, Azure usw.

Verwenden von Aspose.Drawing in ASP.NET-Diensten

Die Aspose.Drawing-Implementierung hängt nicht von GDI oder GDI+ ab. Es verwendet keine GDI-Handles und verwendet selten prozessweite Sperren.

Demonstration für die Verwendung von Aspose.Drawing in ASP.NET-Diensten

Lassen Sie uns eine einfache Anwendung erstellen, die die Vorteile der Verwendung der Aspose.Drawing Bibliothek erklärt:

Stellen Sie sich vor, Sie entscheiden sich, einen völlig neuen Webdienst oder eine Anwendung zu erstellen. Die Anwendung generiert aus dem Bild des Benutzers eine Reihe von Miniaturansichten mit daran angehängten Filtern.

Sie können damit beginnen, einige neue Entitäten einzuführen:

///<summary>
/// Verfügbare Filtertypen.
///</summary>
public enum FilterType
{
    ///<summary>
    /// Filter zur Erzeugung eines mit roter Farbe gesättigten Bildes.
    ///</summary>
    Red,

    ///<summary>
    /// Filter zur Erzeugung eines mit grüner Farbe gesättigten Bildes.
    ///</summary>
    Green,

    ///<summary>
    /// Filter zur Generierung eines mit blauer Farbe gesättigten Bildes.
    ///</summary>
    Blue,

    ///<summary>
    /// Filter zur Generierung eines Graustufenbildes.
    ///</summary>
    Grayscale,

    ///<summary>
    /// Filter zur Erzeugung eines Negativbildes.
    ///</summary>
    Negative,

    ///<summary>
    /// Filter zur Generierung eines Sepia Bildes.
    ///</summary>
    Sepia,
}
///<summary>
/// Das Ergebnis der gefilterten Thumbnail-Generierung.
///</summary>
public class FilterThumbnailResult
{
    ///<summary>
    /// Initialisiert eine neue Instanz der FilterThumbnailResult Klasse.
    ///</summary>
    ///<param name="filterType"> Der Filtertyp, der auf die Miniaturansicht angewendet wird.</param>
    ///<param name="pngData"> Die Bilddaten im PNG-Format.</param>
    ///<param name="width"> Die Breite der Miniaturansicht.</param>
    ///<param name="height"> Die Höhe der Miniaturansicht.</param>
    public FilterThumbnailResult(FilterType filterType, byte[] pngData, int width, int height)
    {
        this.FilterType = filterType;
        this.PngData = pngData;
        this.Width = width;
        this.Height = height;
    }

    ///<summary>
    /// Ruft den Filtertyp ab, der auf die Miniaturansicht angewendet wird.
    ///</summary>
    public FilterType FilterType { get; }

    ///<summary>
    /// Ruft die Bilddaten im PNG Format ab.
    ///</summary>
    public byte[] PngData { get; }

    ///<summary>
    /// Ruft die Breite des Thumbnails ab.
    ///</summary>
    public int Width { get; }

    ///<summary>
    /// Ruft die Höhe des Thumbnails ab.
    ///</summary>
    public int Height { get; }
}

Jetzt können Sie die Schnittstelle für die Generierung von Thumbnails mit angehängten Filtern definieren:

using System.Collections.Generic;

///<summary>
/// Die Schnittstelle für die Generierung von Vorschaubildern.
///</summary>
public interface IThumbnailGenerator
{
    ///<summary>
    /// Erzeugt eine Reihe von Miniaturansichten für alle verfügbaren Filter.
    ///</summary>
    ///<param name="sourceImage"> Bytes des Quellbildes.</param>
    ///<param name="width"> Angeforderte Breite der Vorschaubilder.</param>
    ///<param name="height"> Gewünschte Höhe der Vorschaubilder.</param>
    ///<returns> Eine Reihe von Miniaturansichten.</returns>
    IEnumerable<FilterThumbnailResult> GenerateAllThumbnails(byte[] sourceImage, int width, int height);
}

Fahren Sie mit der Implementierung fort und nehmen Sie an, dass Sie die IThumbnailGenerator-Schnittstelle mithilfe der System.Drawing Bibliothek implementieren. Es sieht aus wie das nächste code snippet:

///<summary>
/// IThumbnailGenerator-Schnittstellenimplementierung mit System.Drawing.
///</summary>
public class ThumbnailGenerator
    : IThumbnailGenerator
{
    ///<summary>
    /// Eine Reihe von Thumbnail-Prozessoren.
    ///</summary>
    private static readonly FilterThumbnailProcessor[] Processors = new FilterThumbnailProcessor[] 
    {
        ApplyRedFilter,
        ApplyGreenFilter,
        ApplyBlueFilter,
        ApplyGrayFilter,
        ApplyNegativeFilter,
        ApplySepiaFilter,
    };

    ///<summary>
    /// Delegierter für die Thumbnail-Verarbeitung.
    ///</summary>
    ///<param name="thumbnail"> Miniaturbild des Originalbildes.</param>
    ///<returns> Ergebnis der gefilterten Thumbnail-Generierung.</returns>
    private delegate FilterThumbnailResult FilterThumbnailProcessor(Bitmap thumbnail);

    ///<summary>
    /// Erzeugt eine Reihe von Miniaturansichten für alle verfügbaren Filter.
    ///</summary>
    ///<param name="sourceImage"> Bytes des Quellbildes.</param>
    ///<param name="width"> Angeforderte Breite der Vorschaubilder.</param>
    ///<param name="height"> Gewünschte Höhe der Vorschaubilder.</param>
    ///<returns> Eine Reihe von Miniaturansichten.</returns>
    public IEnumerable<FilterThumbnailResult> GenerateAllThumbnails(byte[] sourceImage, int width, int height)
    {
        using (MemoryStream ms = new MemoryStream(sourceImage))
        using (Bitmap bitmap = new Bitmap(ms))
        {
            foreach (var processor in Processors)
            {
                using (Bitmap previewBitmap = new Bitmap(width, height, PixelFormat.Format32bppArgb))
                using (Graphics graphics = Graphics.FromImage(previewBitmap))
                {
                    graphics.DrawImage(bitmap, 0, 0, width, height);

                    yield return processor(previewBitmap);
                }
            }
        }
    }

    ///<summary>
    /// Wendet einen roten Filter auf das Miniaturbild an.
    ///</summary>
    ///<param name="thumbnail"> Miniaturbild des Originalbildes.</param>
    ///<returns> Ergebnis der gefilterten Thumbnail-Generierung.</returns>
    private static FilterThumbnailResult ApplyRedFilter(Bitmap thumbnail)
    {
    ...
    }

    ///<summary>
    /// Wendet einen grünen Filter auf das Miniaturbild an.
    ///</summary>
    ///<param name="thumbnail"> Miniaturbild des Originalbildes.</param>
    ///<returns> Ergebnis der gefilterten Thumbnail-Generierung.</returns>
    private static FilterThumbnailResult ApplyGreenFilter(Bitmap thumbnail)
    {
    ...
    }

    ///<summary>
    /// Wendet einen blauen Filter auf das Miniaturbild an.
    ///</summary>
    ///<param name="thumbnail"> Miniaturbild des Originalbildes.</param>
    ///<returns> Ergebnis der gefilterten Thumbnail-Generierung.</returns>
    private static FilterThumbnailResult ApplyBlueFilter(Bitmap thumbnail)
    {
    ...
    }

    ///<summary>
    /// Wendet einen Graufilter auf das Miniaturbild an.
    ///</summary>
    ///<param name="thumbnail"> Miniaturbild des Originalbildes.</param>
    ///<returns> Ergebnis der gefilterten Thumbnail-Generierung.</returns>
    private static FilterThumbnailResult ApplyGrayFilter(Bitmap thumbnail)
    {
    ...
    }

    ///<summary>
    /// Wendet einen negativen Filter auf das Miniaturbild an.
    ///</summary>
    ///<param name="thumbnail"> Miniaturbild des Originalbildes.</param>
    ///<returns> Ergebnis der gefilterten Thumbnail-Generierung.</returns>
    private static FilterThumbnailResult ApplyNegativeFilter(Bitmap thumbnail)
    {
    ...
    }

    ///<summary>
    /// Wendet einen Sepia-Filter auf das Miniaturbild an.
    ///</summary>
    ///<param name="thumbnail"> Miniaturbild des Originalbildes.</param>
    ///<returns> Ergebnis der gefilterten Thumbnail-Generierung.</returns>
    private static FilterThumbnailResult ApplySepiaFilter(Bitmap thumbnail)
    {
    ...
    }
}

Der Code wird gut funktionieren, hat aber einen Nachteil - er generiert alle Thumbnails sequentiell. Die System.Drawing Bibliothek basiert auf einer ziemlich alten GDI+ Bibliothek, die als Single-Thread Bibliothek entworfen wurde, sodass Ressourcen verschwendet werden können, wenn mehrere CPU-Kerne vorhanden sind.

Die Verwendung von Aspose.Drawing kann dazu beitragen, die Leistung erheblich zu verbessern, da es keine Einschränkungen in Bezug auf einen einzelnen Thread gibt. Bitte versuchen Sie, nur eine Funktion zu ändern:

///<summary>
/// Erzeugt eine Reihe von Miniaturansichten für alle verfügbaren Filter.
///</summary>
///<param name="sourceImage"> Bytes des Quellbildes.</param>
///<param name="width"> Angeforderte Breite der Vorschaubilder.</param>
///<param name="height"> Gewünschte Höhe der Vorschaubilder.</param>
///<returns> Eine Reihe von Miniaturansichten.</returns>
public IEnumerable<FilterThumbnailResult> GenerateAllThumbnails(byte[] sourceImage, int width, int height)
{
    using (MemoryStream ms = new MemoryStream(sourceImage))
    using (Bitmap bitmap = new Bitmap(ms))
    {
        ConcurrentBag<FilterThumbnailResult> collection = new ConcurrentBag<FilterThumbnailResult>();

        Parallel.ForEach(Processors, (processor) =>
        {
            using (Bitmap previewBitmap = new Bitmap(width, height, PixelFormat.Format32bppArgb))
            using (Graphics graphics = Graphics.FromImage(previewBitmap))
            {
                graphics.DrawImage(bitmap, 0, 0, width, height);
                collection.Add(processor(previewBitmap));
            }
        });

        return collection;
    }
}

Dieser Code kann nun mehrere CPU-Kerne ohne wesentliche Änderungen im ursprünglichen Quellcode verwenden. Das Ersetzen von System.Drawing durch Aspose.Drawing beschleunigt die Leistung Ihrer Anwendungen und Dienste.

Quellcode herunterladen

Sie können den Quellcode zu diesem Beispiel als Referenz herunterladen.

Kostenlose API-Evaluierungslizenz

Sie können eine kostenlose temporäre Lizenz anfordern, um die API in vollem Umfang zu testen.

Fazit

Zusammenfassend haben Sie anhand von Beispielen gelernt, wie einfach es ist, die Aspose.Drawing Bibliothek in Ihren ASP.NET und ASP.NET Core-Diensten zu verwenden. Darüber hinaus hat Aspose.Drawing keine Probleme oder externen Abhängigkeiten, die in System.Drawing bestehen. Darüber hinaus können Sie die API im Detail erkunden, indem Sie die Dokumentation durchgehen. Bitte zögern Sie nicht, uns jederzeit über das kostenlose Support-Forum zu kontaktieren, wenn Sie Fragen haben!

Siehe auch