System.Drawing ב-ASP .NET ASP.NET Core

יש הרבה שאלות המוקדשות לשימוש בספריית System.Drawing בשירותי ASP.NET. התשובה הנפוצה ביותר היא שמיקרוסופט אינה ממליצה על השימוש ב-System.Drawing בשירותי ASP.NET.

במאמר זה תלמדו פרטים על שימוש בממשק של ספריית System.Drawing בשירותי ASP.NET עם Aspose.Drawing for .NET. הסעיפים הבאים בונים את כל המידע הרלוונטי:

למה Aspose.Drawing?

מיקרוסופט אינה ממליצה על השימוש בספריית System.Drawing שלה בשירותי ASP.NET. בדף הבית של System.Drawing תיעוד נכתב:

מחלקות בתוך מרחב השמות System.Drawing אינן נתמכות לשימוש בתוך שירות Windows או ASP.NET. ניסיון להשתמש במחלקות אלו מתוך אחד מסוגי היישומים הללו עלול לגרום לחריגות בזמן ריצה ולירידה בביצועי השירות.

ישנן שתי בעיות בסיסיות שמחייבות את מיקרוסופט לכתוב זהירות למעלה. הבעיה הראשונה היא השימוש בספרייה המקומית של GDI+ וכתוצאה מכך שימוש בנקודות האחיזה של GDI. בעוד שהחשש השני הוא בעיות במקביל. לדוגמה, נעילה לכל התהליך מתרחשת במהלך כל פעולת DrawImage() . לכן, אינך יכול ליצור שירותי ASP.NET מהירים וניתנים להרחבה באמצעות ספריית System.Drawing של Microsoft.

התקנת Aspose.Drawing עבור .NET API

אתה יכול בקלות להוריד את קובץ ה-DLL מהקטע הורדות או להגדיר אותו באמצעות מנהל החבילות NuGet עם הפקודה הבאה:

PM> Install-Package Aspose.Drawing

Aspose.Drawing עבור .NET API - מבוא

אנו מבינים ש-System.Drawing פופולרי מאוד בקרב מפתחים בגלל תכונות המניפולציה של התמונות שלו. לכן יצרנו API דומה ותואם ללא בעיות תאימות. לנוחיותך ויכולת ההסתגלות שלך, ה-API מכיל את אותם שמות של מחלקות, פונקציות, רשימות וממשקים. אתה יכול פשוט לשנות את ההתייחסות לפרויקט מ-System.Drawing ל-Aspose.Drawing ולהרכיב מחדש את התוכנית.

יתרה מכך, Aspose.Drawing היא ספרייה מנוהלת הזמינה עבור NET Framework 2.0 ו-NET Core 2.0. בניגוד ל-System.Drawing, אין לו תלות באף פלטפורמה כמו לינוקס, Azure וכו'.

שימוש ב-Aspose.Drawing בשירותי ASP.NET

יישום Aspose.Drawing אינו תלוי ב-GDI או GDI+. הוא אינו משתמש בידיות GDI ולעיתים רחוקות משתמש במנעולים לכל התהליך.

הדגמה לשימוש ב-Aspose.Drawing בשירותי ASP.NET

תן לנו ליצור יישום פשוט שמסביר את היתרונות של השימוש בספריית Aspose.Drawing:

תארו לעצמכם שאתם מחליטים ליצור שירות או אפליקציה חדשים לגמרי. האפליקציה תיצור סט תמונות ממוזערות עם פילטרים המצורפים אליהן מתמונת המשתמש.

אתה יכול להתחיל בהצגת כמה ישויות חדשות:

///<summary>
/// סוגים זמינים של המסננים.
///</summary>
public enum FilterType
{
    ///<summary>
    /// מסנן ליצירת תמונה רוויה בצבע אדום.
    ///</summary>
    Red,

    ///<summary>
    /// מסנן ליצירת תמונה רוויה בצבע ירוק.
    ///</summary>
    Green,

    ///<summary>
    /// מסנן ליצירת תמונה רוויה בצבע כחול.
    ///</summary>
    Blue,

    ///<summary>
    /// סינון ליצירת תמונה בגווני אפור.
    ///</summary>
    Grayscale,

    ///<summary>
    /// סינון ליצירת תמונה שלילית.
    ///</summary>
    Negative,

    ///<summary>
    /// סינון ליצירת תמונת ספיה.
    ///</summary>
    Sepia,
}
///<summary>
/// התוצאה של יצירת תמונות ממוזערות מסוננות.
///</summary>
public class FilterThumbnailResult
{
    ///<summary>
    /// מאתחל מופע חדש של המחלקה FilterThumbnailResult.
    ///</summary>
    ///<param name="filterType"> סוג המסנן שהוחל על התמונה הממוזערת.</param>
    ///<param name="pngData"> נתוני התמונה בפורמט PNG.</param>
    ///<param name="width"> רוחב התמונה הממוזערת.</param>
    ///<param name="height"> גובה התמונה הממוזערת.</param>
    public FilterThumbnailResult(FilterType filterType, byte[] pngData, int width, int height)
    {
        this.FilterType = filterType;
        this.PngData = pngData;
        this.Width = width;
        this.Height = height;
    }

    ///<summary>
    /// מקבל את סוג המסנן שהוחל על התמונה הממוזערת.
    ///</summary>
    public FilterType FilterType { get; }

    ///<summary>
    /// מקבל את נתוני התמונה בפורמט PNG.
    ///</summary>
    public byte[] PngData { get; }

    ///<summary>
    /// מקבל את רוחב התמונה הממוזערת.
    ///</summary>
    public int Width { get; }

    ///<summary>
    /// מקבל את גובה התמונה הממוזערת.
    ///</summary>
    public int Height { get; }
}

כעת תוכל להגדיר את הממשק ליצירת תמונות ממוזערות עם מסננים מצורפים:

using System.Collections.Generic;

///<summary>
/// הממשק ליצירת תמונות ממוזערות.
///</summary>
public interface IThumbnailGenerator
{
    ///<summary>
    /// יוצר קבוצה של תמונות ממוזערות עבור כל המסננים הזמינים.
    ///</summary>
    ///<param name="sourceImage"> בייטים של תמונת המקור.</param>
    ///<param name="width"> הרוחב המבוקש של תמונות התצוגה המקדימה.</param>
    ///<param name="height"> הגובה המבוקש של תמונות התצוגה המקדימה.</param>
    ///<returns> סט של תמונות ממוזערות.</returns>
    IEnumerable<FilterThumbnailResult> GenerateAllThumbnails(byte[] sourceImage, int width, int height);
}

עוברים ליישום, נניח שהטמעת ממשק IThumbnailGenerator באמצעות ספריית System.Drawing. זה ייראה כמו קטע הקוד הבא:

///<summary>
/// יישום ממשק IThumbnailGenerator באמצעות System.Drawing.
///</summary>
public class ThumbnailGenerator
    : IThumbnailGenerator
{
    ///<summary>
    /// סט של מעבדי תמונות ממוזערות.
    ///</summary>
    private static readonly FilterThumbnailProcessor[] Processors = new FilterThumbnailProcessor[] 
    {
        ApplyRedFilter,
        ApplyGreenFilter,
        ApplyBlueFilter,
        ApplyGrayFilter,
        ApplyNegativeFilter,
        ApplySepiaFilter,
    };

    ///<summary>
    /// נציג לעיבוד תמונות ממוזערות.
    ///</summary>
    ///<param name="thumbnail"> תמונה ממוזערת של התמונה המקורית.</param>
    ///<returns> תוצאה של יצירת תמונות ממוזערות מסוננות.</returns>
    private delegate FilterThumbnailResult FilterThumbnailProcessor(Bitmap thumbnail);

    ///<summary>
    /// יוצר קבוצה של תמונות ממוזערות עבור כל המסננים הזמינים.
    ///</summary>
    ///<param name="sourceImage"> בייטים של תמונת המקור.</param>
    ///<param name="width"> הרוחב המבוקש של תמונות התצוגה המקדימה.</param>
    ///<param name="height"> הגובה המבוקש של תמונות התצוגה המקדימה.</param>
    ///<returns> סט של תמונות ממוזערות.</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>
    /// מחיל מסנן אדום על התמונה הממוזערת.
    ///</summary>
    ///<param name="thumbnail"> תמונה ממוזערת של התמונה המקורית.</param>
    ///<returns> תוצאה של יצירת תמונות ממוזערות מסוננות.</returns>
    private static FilterThumbnailResult ApplyRedFilter(Bitmap thumbnail)
    {
    ...
    }

    ///<summary>
    /// מחיל מסנן ירוק על התמונה הממוזערת.
    ///</summary>
    ///<param name="thumbnail"> תמונה ממוזערת של התמונה המקורית.</param>
    ///<returns> תוצאה של יצירת תמונות ממוזערות מסוננות.</returns>
    private static FilterThumbnailResult ApplyGreenFilter(Bitmap thumbnail)
    {
    ...
    }

    ///<summary>
    /// מחיל מסנן כחול על התמונה הממוזערת.
    ///</summary>
    ///<param name="thumbnail"> תמונה ממוזערת של התמונה המקורית.</param>
    ///<returns> תוצאה של יצירת תמונות ממוזערות מסוננות.</returns>
    private static FilterThumbnailResult ApplyBlueFilter(Bitmap thumbnail)
    {
    ...
    }

    ///<summary>
    /// מחיל מסנן אפור על התמונה הממוזערת.
    ///</summary>
    ///<param name="thumbnail"> תמונה ממוזערת של התמונה המקורית.</param>
    ///<returns> תוצאה של יצירת תמונות ממוזערות מסוננות.</returns>
    private static FilterThumbnailResult ApplyGrayFilter(Bitmap thumbnail)
    {
    ...
    }

    ///<summary>
    /// מחיל מסנן שלילי על התמונה הממוזערת.
    ///</summary>
    ///<param name="thumbnail"> תמונה ממוזערת של התמונה המקורית.</param>
    ///<returns> תוצאה של יצירת תמונות ממוזערות מסוננות.</returns>
    private static FilterThumbnailResult ApplyNegativeFilter(Bitmap thumbnail)
    {
    ...
    }

    ///<summary>
    /// מחיל מסנן ספיה על התמונה הממוזערת.
    ///</summary>
    ///<param name="thumbnail"> תמונה ממוזערת של התמונה המקורית.</param>
    ///<returns> תוצאה של יצירת תמונות ממוזערות מסוננות.</returns>
    private static FilterThumbnailResult ApplySepiaFilter(Bitmap thumbnail)
    {
    ...
    }
}

הקוד יעבוד מצוין אבל יש לו חיסרון אחד - הוא יוצר את כל התמונות הממוזערות ברצף. ספריית System.Drawing מבוססת על ספריית GDI+ ישנה למדי אשר תוכננה כספריית חוט בודד, כך שהיא יכולה לבזבז משאבים כאשר ישנן מספר ליבות CPU.

שימוש ב-Aspose.Drawing יכול לעזור לשפר משמעותית את הביצועים מכיוון שאין לו מגבלות הקשורות לחוט בודד. אנא נסה לשנות רק פונקציה אחת:

///<summary>
/// יוצר קבוצה של תמונות ממוזערות עבור כל המסננים הזמינים.
///</summary>
///<param name="sourceImage"> בייטים של תמונת המקור.</param>
///<param name="width"> הרוחב המבוקש של תמונות התצוגה המקדימה.</param>
///<param name="height"> הגובה המבוקש של תמונות התצוגה המקדימה.</param>
///<returns> סט של תמונות ממוזערות.</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;
    }
}

קוד זה יכול כעת להשתמש בליבות CPU מרובות ללא שינויים משמעותיים בקוד המקור המקורי. החלפת System.Drawing ב-Aspose.Drawing מזרזת את הביצועים של היישומים והשירותים שלך.

הורד את קוד המקור

אתה יכול להוריד את קוד המקור הקשור לדוגמה זו לעיונך.

רישיון הערכת API בחינם

אתה יכול לבקש Free Temporary License כדי לבדוק את ה-API במלוא קיבולתו.

סיכום

לסיכום, למדת עם דוגמה כמה פשוט להשתמש בספריית Aspose.Drawing בשירותי ASP.NET ו-ASP.NET Core שלך. יתרה מכך, ל-Aspose.Drawing אין בעיות או תלות חיצוניות הקיימות ב-System.Drawing. יתר על כן, אתה יכול לחקור את ה-API בפירוט על ידי מעבר על תיעוד. אנא אל תהסס לפנות אלינו בכל עת דרך פורום תמיכה חינם לכל שאלה שלך!

ראה גם