System.Drawing di ASP .NET ASP.NET Core

Ada banyak pertanyaan yang didedikasikan untuk penggunaan pustaka System.Drawing di layanan ASP.NET. Jawaban paling umum adalah bahwa Microsoft tidak merekomendasikan penggunaan System.Drawing di layanan ASP.NET.

Pada artikel ini, Anda akan mempelajari detail tentang penggunaan antarmuka pustaka System.Drawing di layanan ASP.NET dengan Aspose.Drawing for .NET. Bagian berikut menyusun semua informasi yang relevan:

Mengapa Aspose.Drawing?

Microsoft tidak merekomendasikan penggunaan pustaka System.Drawing di layanan ASP.NET. Halaman beranda System.Drawing dokumentasi berbunyi:

Kelas dalam ruang nama System.Drawing tidak didukung untuk digunakan dalam layanan Windows atau ASP.NET. Mencoba menggunakan kelas-kelas ini dari dalam salah satu jenis aplikasi ini dapat mengakibatkan pengecualian run-time dan penurunan kinerja layanan.

Ada dua masalah mendasar yang memaksa Microsoft untuk menulis di atas dengan hati-hati. Masalah pertama adalah penggunaan pustaka asli GDI+ dan, akibatnya, penggunaan pegangan GDI. Sedangkan perhatian kedua adalah masalah konkurensi. Misalnya, kunci seluruh proses terjadi selama operasi DrawImage() apa pun. Oleh karena itu, Anda tidak dapat membuat layanan ASP.NET yang cepat dan terukur menggunakan pustaka System.Drawing dari Microsoft.

Menginstal Aspose.Drawing for .NET API

Anda dapat dengan mudah mengunduh file DLL dari bagian Unduhan, atau mengonfigurasinya melalui Pengelola paket NuGet dengan perintah berikut:

PM> Install-Package Aspose.Drawing

Aspose.Drawing for .NET API - Pendahuluan

Kami memahami bahwa System.Drawing sangat populer di kalangan pengembang karena fitur manipulasi gambarnya. Itu sebabnya kami membuat API yang serupa dan kompatibel tanpa masalah kompatibilitas. Untuk kenyamanan dan kemampuan beradaptasi Anda, API berisi nama kelas, fungsi, enum, dan antarmuka yang sama. Anda cukup mengubah referensi proyek dari System.Drawing ke Aspose.Drawing dan mengkompilasi ulang program.

Selain itu, Aspose.Drawing adalah pustaka terkelola yang tersedia untuk NET Framework 2.0 dan NET Core 2.0. Tidak seperti System.Drawing, ia tidak memiliki ketergantungan pada platform apa pun seperti Linux, Azure, dll.

Menggunakan Aspose.Drawing di Layanan ASP.NET

Implementasi Aspose.Drawing tidak bergantung pada GDI atau GDI+. Itu tidak menggunakan pegangan GDI dan jarang menggunakan kunci seluruh proses.

Demonstrasi untuk menggunakan Aspose.Drawing di Layanan ASP.NET

Mari kita buat aplikasi sederhana yang menjelaskan manfaat menggunakan library Aspose.Drawing:

Bayangkan Anda memutuskan untuk membuat layanan atau aplikasi web yang benar-benar baru. Aplikasi akan menghasilkan satu set thumbnail dengan filter yang melekat padanya dari gambar pengguna.

Anda dapat memulai dengan memperkenalkan beberapa entitas baru:

///<summary>
/// Jenis filter yang tersedia.
///</summary>
public enum FilterType
{
    ///<summary>
    /// Filter untuk pembuatan gambar jenuh dengan warna merah.
    ///</summary>
    Red,

    ///<summary>
    /// Filter untuk pembuatan gambar jenuh dengan warna hijau.
    ///</summary>
    Green,

    ///<summary>
    /// Filter untuk menghasilkan gambar yang jenuh dengan warna biru.
    ///</summary>
    Blue,

    ///<summary>
    /// Filter untuk pembuatan gambar skala abu-abu.
    ///</summary>
    Grayscale,

    ///<summary>
    /// Filter untuk menghasilkan citra negatif.
    ///</summary>
    Negative,

    ///<summary>
    /// Filter untuk pembuatan gambar sepia.
    ///</summary>
    Sepia,
}
///<summary>
/// Hasil pembuatan thumbnail yang difilter.
///</summary>
public class FilterThumbnailResult
{
    ///<summary>
    /// Menginisialisasi instance baru dari kelas FilterThumbnailResult.
    ///</summary>
    ///<param name="filterType"> Jenis filter yang diterapkan pada thumbnail.</param>
    ///<param name="pngData"> Data gambar dalam format PNG.</param>
    ///<param name="width"> Lebar thumbnail.</param>
    ///<param name="height"> Tinggi thumbnail.</param>
    public FilterThumbnailResult(FilterType filterType, byte[] pngData, int width, int height)
    {
        this.FilterType = filterType;
        this.PngData = pngData;
        this.Width = width;
        this.Height = height;
    }

    ///<summary>
    /// Mendapat jenis filter yang diterapkan pada thumbnail.
    ///</summary>
    public FilterType FilterType { get; }

    ///<summary>
    /// Mendapat data gambar dalam format PNG.
    ///</summary>
    public byte[] PngData { get; }

    ///<summary>
    /// Mendapatkan lebar thumbnail.
    ///</summary>
    public int Width { get; }

    ///<summary>
    /// Mendapatkan tinggi thumbnail.
    ///</summary>
    public int Height { get; }
}

Sekarang Anda dapat menentukan antarmuka untuk pembuatan thumbnail dengan filter terlampir:

using System.Collections.Generic;

///<summary>
/// Antarmuka untuk pembuatan gambar mini.
///</summary>
public interface IThumbnailGenerator
{
    ///<summary>
    /// Menghasilkan satu set thumbnail untuk semua filter yang tersedia.
    ///</summary>
    ///<param name="sourceImage"> Byte dari gambar sumber.</param>
    ///<param name="width"> Lebar yang diminta dari gambar pratinjau.</param>
    ///<param name="height"> Tinggi yang diminta dari gambar pratinjau.</param>
    ///<returns> Satu set thumbnail.</returns>
    IEnumerable<FilterThumbnailResult> GenerateAllThumbnails(byte[] sourceImage, int width, int height);
}

Pindah ke implementasi, asumsikan mengimplementasikan antarmuka IThumbnailGenerator menggunakan pustaka System.Drawing. Ini akan terlihat seperti cuplikan kode berikutnya:

///<summary>
/// Implementasi antarmuka IThumbnailGenerator menggunakan System.Drawing.
///</summary>
public class ThumbnailGenerator
    : IThumbnailGenerator
{
    ///<summary>
    /// Satu set prosesor thumbnail.
    ///</summary>
    private static readonly FilterThumbnailProcessor[] Processors = new FilterThumbnailProcessor[] 
    {
        ApplyRedFilter,
        ApplyGreenFilter,
        ApplyBlueFilter,
        ApplyGrayFilter,
        ApplyNegativeFilter,
        ApplySepiaFilter,
    };

    ///<summary>
    /// Delegasi untuk pemrosesan thumbnail.
    ///</summary>
    ///<param name="thumbnail"> Thumbnail dari gambar asli.</param>
    ///<returns> Hasil pembuatan thumbnail yang difilter.</returns>
    private delegate FilterThumbnailResult FilterThumbnailProcessor(Bitmap thumbnail);

    ///<summary>
    /// Menghasilkan satu set thumbnail untuk semua filter yang tersedia.
    ///</summary>
    ///<param name="sourceImage"> Byte dari gambar sumber.</param>
    ///<param name="width"> Lebar yang diminta dari gambar pratinjau.</param>
    ///<param name="height"> Tinggi yang diminta dari gambar pratinjau.</param>
    ///<returns> Satu set thumbnail.</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>
    /// Menerapkan filter merah ke thumbnail.
    ///</summary>
    ///<param name="thumbnail"> Thumbnail dari gambar asli.</param>
    ///<returns> Hasil pembuatan thumbnail yang difilter.</returns>
    private static FilterThumbnailResult ApplyRedFilter(Bitmap thumbnail)
    {
    ...
    }

    ///<summary>
    /// Menerapkan filter hijau ke thumbnail.
    ///</summary>
    ///<param name="thumbnail"> Thumbnail dari gambar asli.</param>
    ///<returns> Hasil pembuatan thumbnail yang difilter.</returns>
    private static FilterThumbnailResult ApplyGreenFilter(Bitmap thumbnail)
    {
    ...
    }

    ///<summary>
    /// Menerapkan filter biru ke thumbnail.
    ///</summary>
    ///<param name="thumbnail"> Thumbnail dari gambar asli.</param>
    ///<returns> Hasil pembuatan thumbnail yang difilter.</returns>
    private static FilterThumbnailResult ApplyBlueFilter(Bitmap thumbnail)
    {
    ...
    }

    ///<summary>
    /// Menerapkan filter abu-abu ke thumbnail.
    ///</summary>
    ///<param name="thumbnail"> Thumbnail dari gambar asli.</param>
    ///<returns> Hasil pembuatan thumbnail yang difilter.</returns>
    private static FilterThumbnailResult ApplyGrayFilter(Bitmap thumbnail)
    {
    ...
    }

    ///<summary>
    /// Menerapkan filter negatif ke thumbnail.
    ///</summary>
    ///<param name="thumbnail"> Thumbnail dari gambar asli.</param>
    ///<returns> Hasil pembuatan thumbnail yang difilter.</returns>
    private static FilterThumbnailResult ApplyNegativeFilter(Bitmap thumbnail)
    {
    ...
    }

    ///<summary>
    /// Menerapkan filter sepia ke thumbnail.
    ///</summary>
    ///<param name="thumbnail"> Thumbnail dari gambar asli.</param>
    ///<returns> Hasil pembuatan thumbnail yang difilter.</returns>
    private static FilterThumbnailResult ApplySepiaFilter(Bitmap thumbnail)
    {
    ...
    }
}

Kode akan berfungsi dengan baik tetapi memiliki satu kelemahan - menghasilkan semua thumbnail secara berurutan. Pustaka System.Drawing didasarkan pada pustaka GDI+ yang cukup lama yang dirancang sebagai pustaka utas tunggal sehingga dapat membuang sumber daya saat ada banyak inti CPU.

Menggunakan Aspose.Drawing dapat membantu meningkatkan kinerja secara signifikan karena tidak memiliki batasan terkait dengan utas tunggal. Silakan coba ubah hanya satu fungsi:

///<summary>
/// Menghasilkan satu set thumbnail untuk semua filter yang tersedia.
///</summary>
///<param name="sourceImage"> Byte dari gambar sumber.</param>
///<param name="width"> Lebar yang diminta dari gambar pratinjau.</param>
///<param name="height"> Tinggi yang diminta dari gambar pratinjau.</param>
///<returns> Satu set thumbnail.</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;
    }
}

Kode ini sekarang dapat menggunakan banyak inti CPU tanpa perubahan signifikan pada kode sumber aslinya. Mengganti System.Drawing dengan Aspose.Drawing mempercepat kinerja aplikasi dan layanan Anda.

Unduh Kode Sumber

Anda dapat mengunduh Kode Sumber terkait dengan contoh ini untuk referensi Anda.

Lisensi Evaluasi API gratis

Anda dapat meminta Lisensi Sementara Gratis untuk menguji API dalam kapasitas penuhnya.

Kesimpulan

Sebagai kesimpulan, Anda telah belajar dengan contoh betapa sederhananya menggunakan pustaka Aspose.Drawing di layanan ASP.NET dan ASP.NET Core Anda. Selain itu, Aspose.Drawing tidak memiliki masalah atau ketergantungan eksternal yang ada di System.Drawing. Selanjutnya, Anda dapat menjelajahi API secara mendetail melalui Dokumentasi. Jangan ragu untuk menghubungi kami kapan saja melalui Forum Dukungan Gratis untuk setiap pertanyaan Anda!

Lihat juga