System.Drawing في ASP.NET ASP.NET Core

هناك الكثير من الأسئلة المخصصة لاستخدام مكتبة الرسم System.Drawing في خدمات ASP.NET. الإجابة الأكثر شيوعًا هي أن Microsoft لا توصي باستخدام System.Drawing في خدمات ASP.NET.

في هذه المقالة ، ستتعلم تفاصيل حول استخدام واجهة مكتبة System.Drawing في خدمات ASP.NET مع Aspose.Drawing for .NET. تعمل الأقسام التالية على تنظيم جميع المعلومات ذات الصلة:

لماذا Aspose.Drawing؟

لا تنصح Microsoft باستخدام مكتبة System.Drawing الخاصة بها في خدمات ASP.NET. تقرأ الصفحة الرئيسية لـ System.Drawing التوثيق:

الفئات داخل System.Drawing مساحة الاسم غير مدعومة للاستخدام ضمن خدمة Windows أو ASP.NET. قد تؤدي محاولة استخدام هذه الفئات من داخل أحد أنواع التطبيقات هذه إلى استثناءات وقت التشغيل وانخفاض أداء الخدمة.

هناك مشكلتان أساسيتان تجبران Microsoft على كتابة الحذر أعلاه. المشكلة الأولى هي استخدام مكتبة GDI + الأصلية ، ونتيجة لذلك ، استخدام مقابض GDI. في حين أن الشاغل الثاني هو قضايا التزامن. على سبيل المثال ، يحدث قفل على مستوى العملية أثناء أي عملية DrawImage().لذلك ، لا يمكنك إنشاء خدمات ASP.NET سريعة وقابلة للتطوير باستخدام مكتبة System.Drawing من Microsoft.

تثبيت Aspose.Drawing لـ .NET API

يمكنك بسهولة تنزيل ملف DLL من قسم التنزيلات ، أو تهيئته عبر مدير الحزم NuGet باستخدام الأمر التالي:

PM> Install-Package Aspose.Drawing

Aspose.Drawing for .NET API - مقدمة

نحن نتفهم أن System.Drawing يحظى بشعبية كبيرة بين المطورين بسبب ميزات التلاعب بالصور. هذا هو السبب في أننا أنشأنا واجهة برمجة تطبيقات مماثلة ومتوافقة دون أي مشاكل في التوافق. لراحتك وقدرتك على التكيف ، تحتوي واجهة برمجة التطبيقات على نفس أسماء الفئات والوظائف والتعدادات والواجهات. يمكنك ببساطة تغيير مرجع المشروع من System.Drawing إلى Aspose.Drawing وإعادة ترجمة البرنامج.

علاوة على ذلك ، Aspose.Drawing هي مكتبة مُدارة متاحة لـ NET Framework 2.0 و NET Core 2.0. على عكس System.Drawing ، ليس له أي تبعيات على أي نظام أساسي مثل Linux و 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 + القديمة التي تم تصميمها كمكتبة خيطية واحدة بحيث يمكنها إهدار الموارد عندما يكون هناك العديد من مراكز وحدة المعالجة المركزية.

يمكن أن يساعد استخدام 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;
    }
}

يمكن لهذا الرمز الآن استخدام نوى متعددة لوحدة المعالجة المركزية دون أي تغييرات كبيرة في شفرة المصدر الأصلية. استبدال System.Drawing مع Aspose.Drawing يسرع أداء تطبيقاتك وخدماتك.

تحميل شفرة المصدر

يمكنك تنزيل Source Code المتعلق بهذا المثال كمرجع لك.

رخصة تقييم API مجانية

يمكنك طلب ترخيص مجاني مؤقت لاختبار API بكامل طاقتها.

استنتاج

في الختام ، لقد تعلمت بمثال مدى سهولة استخدام مكتبة Aspose.Drawing في خدمات ASP.NET و ASP.NET Core. علاوة على ذلك ، Aspose.Drawing ليس لديه مشاكل أو تبعيات خارجية موجودة في System.Drawing. علاوة على ذلك ، يمكنك استكشاف API بالتفصيل من خلال الاطلاع على الوثائق. لا تتردد في الاتصال بنا في أي وقت عبر منتدى الدعم المجاني لأي من استفساراتك!

أنظر أيضا