System.Drawing i ASP .NET ASP.NET Core

Det finns många frågor ägnade åt användningen av System.Drawing-biblioteket i ASP.NET-tjänster. Det vanligaste svaret är att Microsoft inte rekommenderar användning av System.Drawing i ASP.NET-tjänster.

I den här artikeln kommer du att lära dig detaljer om hur du använder gränssnittet för System.Drawing-biblioteket i ASP.NET-tjänster med Aspose.Drawing for .NET. Följande avsnitt strukturerar all relevant information:

Varför Aspose.Drawing?

Microsoft rekommenderar inte användning av dess System.Drawing-bibliotek i ASP.NET-tjänster. Hemsidan för System.Drawing dokumentation lyder:

Klasser inom namnområdet System.Drawing stöds inte för användning inom en Windows- eller ASP.NET-tjänst. Försök att använda dessa klasser från en av dessa applikationstyper kan resultera i körtidsundantag och försämrad tjänstprestanda.

Det finns två grundläggande problem som tvingar Microsoft att skriva ovanför försiktighet. Det första problemet är användningen av GDI+ inbyggda bibliotek och, som ett resultat, användningen av GDI-handtag. Medan den andra frågan är samtidighetsfrågor. Till exempel inträffar ett processomfattande lås under någon DrawImage()-operation. Därför kan du inte skapa snabba och skalbara ASP.NET-tjänster med hjälp av System.Drawing-biblioteket från Microsoft.

Installera Aspose.Drawing för .NET API

Du kan enkelt ladda ner DLL-filen från avsnittet Nedladdningar eller konfigurera den via pakethanteraren NuGet med följande kommando:

PM> Install-Package Aspose.Drawing

Aspose.Drawing för .NET API - Introduktion

Vi förstår att System.Drawing är mycket populärt bland utvecklare på grund av dess bildmanipuleringsfunktioner. Det är därför vi har skapat ett liknande och kompatibelt API utan några kompatibilitetsproblem. För din bekvämlighet och anpassningsförmåga innehåller API:et samma namn på klasser, funktioner, uppräkningar och gränssnitt. Du kan helt enkelt ändra projektreferensen från System.Drawing till Aspose.Drawing och kompilera om programmet.

Dessutom är Aspose.Drawing ett hanterat bibliotek tillgängligt för NET Framework 2.0 och NET Core 2.0. Till skillnad från System.Drawing har den inga beroenden på någon plattform som Linux, Azure, etc.

Använda Aspose.Drawing i ASP.NET Services

Implementeringen av Aspose.Drawing är inte beroende av GDI eller GDI+. Den använder inte GDI-handtag och använder sällan processomfattande lås.

Demonstration för användning av Aspose.Drawing i ASP.NET Services

Låt oss skapa en enkel applikation som förklarar fördelarna med att använda Aspose.Drawing-biblioteket:

Föreställ dig att du bestämmer dig för att skapa en helt ny webbtjänst eller applikation. Applikationen kommer att generera en uppsättning miniatyrer med filter kopplade till dem från användarens bild.

Du kan börja med att introducera några nya enheter:

///<summary>
/// Tillgängliga typer av filter.
///</summary>
public enum FilterType
{
    ///<summary>
    /// Filter för generering av bild mättad med röd färg.
    ///</summary>
    Red,

    ///<summary>
    /// Filter för generering av bild mättad med grön färg.
    ///</summary>
    Green,

    ///<summary>
    /// Filter för generering av bild mättad med blå färg.
    ///</summary>
    Blue,

    ///<summary>
    /// Filter för generering av en gråskalebild.
    ///</summary>
    Grayscale,

    ///<summary>
    /// Filter för generering av en negativ bild.
    ///</summary>
    Negative,

    ///<summary>
    /// Filter för generering av en sepiabild.
    ///</summary>
    Sepia,
}
///<summary>
/// Resultatet av generering av filtrerade miniatyrer.
///</summary>
public class FilterThumbnailResult
{
    ///<summary>
    /// Initierar en ny instans av klassen FilterThumbnailResult.
    ///</summary>
    ///<param name="filterType"> Typen av filter som tillämpas på miniatyren.</param>
    ///<param name="pngData"> Bilddata i PNG-format.</param>
    ///<param name="width"> Miniatyrens bredd.</param>
    ///<param name="height"> Höjden på miniatyrbilden.</param>
    public FilterThumbnailResult(FilterType filterType, byte[] pngData, int width, int height)
    {
        this.FilterType = filterType;
        this.PngData = pngData;
        this.Width = width;
        this.Height = height;
    }

    ///<summary>
    /// Hämtar typen av filter som tillämpas på miniatyren.
    ///</summary>
    public FilterType FilterType { get; }

    ///<summary>
    /// Hämtar bilddata i PNG-format.
    ///</summary>
    public byte[] PngData { get; }

    ///<summary>
    /// Får bredden på miniatyrbilden.
    ///</summary>
    public int Width { get; }

    ///<summary>
    /// Får höjden på miniatyrbilden.
    ///</summary>
    public int Height { get; }
}

Nu kan du definiera gränssnittet för generering av miniatyrer med bifogade filter:

using System.Collections.Generic;

///<summary>
/// Gränssnittet för generering av miniatyrbilder.
///</summary>
public interface IThumbnailGenerator
{
    ///<summary>
    /// Genererar en uppsättning miniatyrer för alla tillgängliga filter.
    ///</summary>
    ///<param name="sourceImage"> Bytes av källbilden.</param>
    ///<param name="width"> Begärd bredd på förhandsgranskningsbilderna.</param>
    ///<param name="height"> Begärd höjd på förhandsgranskningsbilderna.</param>
    ///<returns> En uppsättning miniatyrer.</returns>
    IEnumerable<FilterThumbnailResult> GenerateAllThumbnails(byte[] sourceImage, int width, int height);
}

Gå vidare till implementeringen, anta att du implementerar IThumbnailGenerator-gränssnittet med System.Drawing-biblioteket. Det kommer att se ut som nästa kodavsnitt:

///<summary>
/// IThumbnailGenerator-gränssnittsimplementering med System.Drawing.
///</summary>
public class ThumbnailGenerator
    : IThumbnailGenerator
{
    ///<summary>
    /// En uppsättning miniatyrbildsprocessorer.
    ///</summary>
    private static readonly FilterThumbnailProcessor[] Processors = new FilterThumbnailProcessor[] 
    {
        ApplyRedFilter,
        ApplyGreenFilter,
        ApplyBlueFilter,
        ApplyGrayFilter,
        ApplyNegativeFilter,
        ApplySepiaFilter,
    };

    ///<summary>
    /// Delegera för bearbetning av miniatyrbilder.
    ///</summary>
    ///<param name="thumbnail"> Miniatyrbild av originalbilden.</param>
    ///<returns> Resultat av generering av filtrerade miniatyrer.</returns>
    private delegate FilterThumbnailResult FilterThumbnailProcessor(Bitmap thumbnail);

    ///<summary>
    /// Genererar en uppsättning miniatyrer för alla tillgängliga filter.
    ///</summary>
    ///<param name="sourceImage"> Bytes av källbilden.</param>
    ///<param name="width"> Begärd bredd på förhandsgranskningsbilderna.</param>
    ///<param name="height"> Begärd höjd på förhandsgranskningsbilderna.</param>
    ///<returns> En uppsättning miniatyrer.</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>
    /// Tillämpar ett rött filter på miniatyrbilden.
    ///</summary>
    ///<param name="thumbnail"> Miniatyrbild av originalbilden.</param>
    ///<returns> Resultat av generering av filtrerade miniatyrer.</returns>
    private static FilterThumbnailResult ApplyRedFilter(Bitmap thumbnail)
    {
    ...
    }

    ///<summary>
    /// Tillämpar ett grönt filter på miniatyrbilden.
    ///</summary>
    ///<param name="thumbnail"> Miniatyrbild av originalbilden.</param>
    ///<returns> Resultat av generering av filtrerade miniatyrer.</returns>
    private static FilterThumbnailResult ApplyGreenFilter(Bitmap thumbnail)
    {
    ...
    }

    ///<summary>
    /// Tillämpar ett blått filter på miniatyrbilden.
    ///</summary>
    ///<param name="thumbnail"> Miniatyrbild av originalbilden.</param>
    ///<returns> Resultat av generering av filtrerade miniatyrer.</returns>
    private static FilterThumbnailResult ApplyBlueFilter(Bitmap thumbnail)
    {
    ...
    }

    ///<summary>
    /// Tillämpar ett grått filter på miniatyrbilden.
    ///</summary>
    ///<param name="thumbnail"> Miniatyrbild av originalbilden.</param>
    ///<returns> Resultat av generering av filtrerade miniatyrer.</returns>
    private static FilterThumbnailResult ApplyGrayFilter(Bitmap thumbnail)
    {
    ...
    }

    ///<summary>
    /// Tillämpar ett negativt filter på miniatyrbilden.
    ///</summary>
    ///<param name="thumbnail"> Miniatyrbild av originalbilden.</param>
    ///<returns> Resultat av generering av filtrerade miniatyrer.</returns>
    private static FilterThumbnailResult ApplyNegativeFilter(Bitmap thumbnail)
    {
    ...
    }

    ///<summary>
    /// Tillämpar ett sepiafilter på miniatyrbilden.
    ///</summary>
    ///<param name="thumbnail"> Miniatyrbild av originalbilden.</param>
    ///<returns> Resultat av generering av filtrerade miniatyrer.</returns>
    private static FilterThumbnailResult ApplySepiaFilter(Bitmap thumbnail)
    {
    ...
    }
}

Koden kommer att fungera bra men den har en nackdel - den genererar alla miniatyrer sekventiellt. System.Drawing-biblioteket är baserat på ett ganska gammalt GDI+-bibliotek som designades som entrådsbibliotek så att det kan slösa resurser när det finns flera CPU-kärnor.

Att använda Aspose.Drawing kan bidra till att avsevärt förbättra prestandan eftersom den inte har några begränsningar relaterade till en enda tråd. Försök att bara ändra en funktion:

///<summary>
/// Genererar en uppsättning miniatyrer för alla tillgängliga filter.
///</summary>
///<param name="sourceImage"> Bytes av källbilden.</param>
///<param name="width"> Begärd bredd på förhandsgranskningsbilderna.</param>
///<param name="height"> Begärd höjd på förhandsgranskningsbilderna.</param>
///<returns> En uppsättning miniatyrer.</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;
    }
}

Denna kod kan nu använda flera CPU-kärnor utan några betydande ändringar i den ursprungliga källkoden. Att ersätta System.Drawing med Aspose.Drawing påskyndar prestandan för dina applikationer och tjänster.

Ladda ner källkod

Du kan ladda ner Källkoden relaterad till detta exempel för din referens.

Gratis API-utvärderingslicens

Du kan begära en Free Temporary License för att testa API:t i dess fulla kapacitet.

Slutsats

Sammanfattningsvis har du med exempel lärt dig hur enkelt det är att använda Aspose.Drawing-biblioteket i dina ASP.NET och ASP.NET Core-tjänster. Dessutom har Aspose.Drawing inga problem eller externa beroenden som finns i System.Drawing. Dessutom kan du utforska API:et i detalj genom att gå igenom Dokumentation. Vänligen kontakta oss när som helst via Free Support Forum för alla dina frågor!

Se även