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 مایکروسافت ایجاد کنید.

نصب Aspose.Drawing برای NET API

می توانید به راحتی فایل DLL را از بخش Downloads دانلود کنید، یا آن را از طریق NuGet package Manager با دستور زیر پیکربندی کنید:

PM> Install-Package Aspose.Drawing

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

ما می دانیم که System.Drawing به دلیل ویژگی های دستکاری تصویر در بین توسعه دهندگان بسیار محبوب است. به همین دلیل است که ما یک API مشابه و سازگار بدون هیچ گونه مشکل سازگاری ایجاد کرده ایم. برای راحتی و سازگاری شما، API شامل همان نام‌های کلاس‌ها، توابع، فهرست‌ها و رابط‌ها است. شما به سادگی می توانید مرجع پروژه را از System.Drawing به Aspose.Drawing تغییر دهید و برنامه را دوباره کامپایل کنید.

علاوه بر این، Aspose.Drawing یک کتابخانه مدیریت شده است که برای NET Framework 2.0 و NET Core 2.0 در دسترس است. برخلاف System.Drawing، هیچ وابستگی به هیچ پلتفرمی مانند لینوکس، آژور و غیره ندارد.

استفاده از 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

می‌توانید برای آزمایش API در ظرفیت کامل، یک مجوز موقت رایگان درخواست کنید.

نتیجه

در پایان، با مثال یاد گرفتید که چقدر ساده است که از کتابخانه Aspose.Drawing در خدمات ASP.NET و ASP.NET Core خود استفاده کنید. علاوه بر این، Aspose.Drawing هیچ مشکل یا وابستگی خارجی در System.Drawing ندارد. علاوه بر این، می‌توانید API را با مراجعه به [اسناد7 با جزئیات بررسی کنید. لطفاً در هر زمان از طریق تالار گفتمان پشتیبانی رایگان برای هر یک از سؤالات خود با ما تماس بگیرید!

همچنین ببینید