System.Drawing trong ASP .NET ASP.NET Core

Có rất nhiều câu hỏi dành riêng cho việc sử dụng thư viện System.Drawing trong các dịch vụ ASP.NET. Câu trả lời phổ biến nhất là Microsoft không khuyến nghị sử dụng System.Drawing trong các dịch vụ ASP.NET.

Trong bài viết này, bạn sẽ tìm hiểu chi tiết về cách sử dụng giao diện của thư viện System.Drawing trong các dịch vụ ASP.NET với Aspose.Drawing for .NET. Các phần sau đây cấu trúc tất cả các thông tin có liên quan:

Tại sao lại là Aspose.Drawing?

Microsoft không khuyến nghị sử dụng thư viện System.Drawing của mình trong các dịch vụ ASP.NET. Trang chủ của System.Drawing tài liệu cho biết:

Các lớp trong không gian tên System.Drawing không được hỗ trợ để sử dụng trong dịch vụ Windows hoặc ASP.NET. Việc cố gắng sử dụng các lớp này từ bên trong một trong các loại ứng dụng này có thể dẫn đến ngoại lệ thời gian chạy và giảm hiệu suất dịch vụ.

Có hai vấn đề cơ bản buộc Microsoft phải thận trọng ở trên. Vấn đề đầu tiên là việc sử dụng thư viện gốc GDI + và kết quả là việc sử dụng các xử lý GDI. Trong khi mối quan tâm thứ hai là vấn đề đồng thời. Ví dụ, một khóa toàn bộ quá trình xảy ra trong bất kỳ hoạt động DrawImage() nào. Do đó, bạn không thể tạo dịch vụ ASP.NET nhanh và có thể mở rộng bằng thư viện System.Drawing của Microsoft.

Cài đặt Aspose.Drawing cho .NET API

Bạn có thể dễ dàng tải xuống tệp DLL từ phần Tải xuống hoặc định cấu hình nó qua Trình quản lý gói NuGet bằng lệnh sau:

PM> Install-Package Aspose.Drawing

Aspose.Drawing cho .NET API - Giới thiệu

Chúng tôi hiểu rằng System.Drawing rất phổ biến trong số các nhà phát triển vì các tính năng thao tác hình ảnh của nó. Đó là lý do tại sao chúng tôi đã tạo một API tương tự và tương thích mà không có bất kỳ vấn đề tương thích nào. Để thuận tiện cho bạn và khả năng thích ứng, API chứa cùng tên của các lớp, hàm, enums và giao diện. Bạn chỉ cần thay đổi tham chiếu dự án từ System.Drawing thành Aspose.Drawing và biên dịch lại chương trình.

Hơn nữa, Aspose.Drawing là một thư viện được quản lý có sẵn cho NET Framework 2.0 và NET Core 2.0. Không giống như System.Drawing, nó không phụ thuộc vào bất kỳ nền tảng nào như Linux, Azure, v.v.

Sử dụng Aspose.Drawing trong Dịch vụ ASP.NET

Việc triển khai Aspose.Drawing không phụ thuộc vào GDI hoặc GDI +. Nó không sử dụng tay cầm GDI và hiếm khi sử dụng khóa toàn bộ quá trình.

Trình diễn việc sử dụng Aspose.Drawing trong Dịch vụ ASP.NET

Hãy để chúng tôi tạo một ứng dụng đơn giản giải thích những lợi ích của việc sử dụng thư viện Aspose.Drawing:

Hãy tưởng tượng rằng bạn quyết định tạo một ứng dụng hoặc dịch vụ web hoàn toàn mới. Ứng dụng sẽ tạo ra một tập hợp các hình thu nhỏ với các bộ lọc được gắn vào chúng từ hình ảnh của người dùng.

Bạn có thể bắt đầu bằng cách giới thiệu một số thực thể mới:

///<summary>
/// Các loại bộ lọc có sẵn.
///</summary>
public enum FilterType
{
    ///<summary>
    /// Bộ lọc để tạo ra hình ảnh bão hòa với màu đỏ.
    ///</summary>
    Red,

    ///<summary>
    /// Bộ lọc để tạo ra hình ảnh bão hòa với màu xanh lá cây.
    ///</summary>
    Green,

    ///<summary>
    /// Bộ lọc để tạo ra hình ảnh bão hòa với màu xanh lam.
    ///</summary>
    Blue,

    ///<summary>
    /// Bộ lọc để tạo hình ảnh thang độ xám.
    ///</summary>
    Grayscale,

    ///<summary>
    /// Bộ lọc để tạo hình ảnh âm bản.
    ///</summary>
    Negative,

    ///<summary>
    /// Bộ lọc để tạo hình ảnh màu nâu đỏ.
    ///</summary>
    Sepia,
}
///<summary>
/// Kết quả của việc tạo hình thu nhỏ đã lọc.
///</summary>
public class FilterThumbnailResult
{
    ///<summary>
    /// Khởi tạo một phiên bản mới của lớp FilterThumbnailResult.
    ///</summary>
    ///<param name="filterType"> Loại bộ lọc được áp dụng cho hình thu nhỏ.</param>
    ///<param name="pngData"> Dữ liệu hình ảnh ở định dạng PNG.</param>
    ///<param name="width"> Chiều rộng của hình thu nhỏ.</param>
    ///<param name="height"> Chiều cao của hình thu nhỏ.</param>
    public FilterThumbnailResult(FilterType filterType, byte[] pngData, int width, int height)
    {
        this.FilterType = filterType;
        this.PngData = pngData;
        this.Width = width;
        this.Height = height;
    }

    ///<summary>
    /// Nhận loại bộ lọc được áp dụng cho hình thu nhỏ.
    ///</summary>
    public FilterType FilterType { get; }

    ///<summary>
    /// Nhận dữ liệu hình ảnh ở định dạng PNG.
    ///</summary>
    public byte[] PngData { get; }

    ///<summary>
    /// Nhận chiều rộng của hình thu nhỏ.
    ///</summary>
    public int Width { get; }

    ///<summary>
    /// Lấy chiều cao của hình thu nhỏ.
    ///</summary>
    public int Height { get; }
}

Bây giờ bạn có thể xác định giao diện cho việc tạo hình thu nhỏ với các bộ lọc đính kèm:

using System.Collections.Generic;

///<summary>
/// Giao diện tạo hình ảnh thu nhỏ.
///</summary>
public interface IThumbnailGenerator
{
    ///<summary>
    /// Tạo một tập hợp các hình thu nhỏ cho tất cả các bộ lọc có sẵn.
    ///</summary>
    ///<param name="sourceImage"> Số byte của hình ảnh nguồn.</param>
    ///<param name="width"> Chiều rộng yêu cầu của hình ảnh xem trước.</param>
    ///<param name="height"> Chiều cao yêu cầu của hình ảnh xem trước.</param>
    ///<returns> Một tập hợp các hình thu nhỏ.</returns>
    IEnumerable<FilterThumbnailResult> GenerateAllThumbnails(byte[] sourceImage, int width, int height);
}

Chuyển sang phần triển khai, giả sử triển khai giao diện IThumbnailGenerator bằng thư viện System.Drawing. Nó sẽ giống như đoạn mã tiếp theo:

///<summary>
/// Triển khai giao diện IThumbnailGenerator bằng System.Drawing.
///</summary>
public class ThumbnailGenerator
    : IThumbnailGenerator
{
    ///<summary>
    /// Một tập hợp các bộ xử lý hình thu nhỏ.
    ///</summary>
    private static readonly FilterThumbnailProcessor[] Processors = new FilterThumbnailProcessor[] 
    {
        ApplyRedFilter,
        ApplyGreenFilter,
        ApplyBlueFilter,
        ApplyGrayFilter,
        ApplyNegativeFilter,
        ApplySepiaFilter,
    };

    ///<summary>
    /// Ủy quyền xử lý hình thu nhỏ.
    ///</summary>
    ///<param name="thumbnail"> Hình thu nhỏ của hình ảnh gốc.</param>
    ///<returns> Kết quả tạo hình thu nhỏ đã lọc.</returns>
    private delegate FilterThumbnailResult FilterThumbnailProcessor(Bitmap thumbnail);

    ///<summary>
    /// Tạo một tập hợp các hình thu nhỏ cho tất cả các bộ lọc có sẵn.
    ///</summary>
    ///<param name="sourceImage"> Số byte của hình ảnh nguồn.</param>
    ///<param name="width"> Chiều rộng yêu cầu của hình ảnh xem trước.</param>
    ///<param name="height"> Chiều cao yêu cầu của hình ảnh xem trước.</param>
    ///<returns> Một tập hợp các hình thu nhỏ.</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>
    /// Áp dụng bộ lọc màu đỏ cho hình thu nhỏ.
    ///</summary>
    ///<param name="thumbnail"> Hình thu nhỏ của hình ảnh gốc.</param>
    ///<returns> Kết quả tạo hình thu nhỏ đã lọc.</returns>
    private static FilterThumbnailResult ApplyRedFilter(Bitmap thumbnail)
    {
    ...
    }

    ///<summary>
    /// Áp dụng bộ lọc màu xanh lá cây cho hình thu nhỏ.
    ///</summary>
    ///<param name="thumbnail"> Hình thu nhỏ của hình ảnh gốc.</param>
    ///<returns> Kết quả tạo hình thu nhỏ đã lọc.</returns>
    private static FilterThumbnailResult ApplyGreenFilter(Bitmap thumbnail)
    {
    ...
    }

    ///<summary>
    /// Áp dụng bộ lọc màu xanh lam cho hình thu nhỏ.
    ///</summary>
    ///<param name="thumbnail"> Hình thu nhỏ của hình ảnh gốc.</param>
    ///<returns> Kết quả tạo hình thu nhỏ đã lọc.</returns>
    private static FilterThumbnailResult ApplyBlueFilter(Bitmap thumbnail)
    {
    ...
    }

    ///<summary>
    /// Áp dụng bộ lọc màu xám cho hình thu nhỏ.
    ///</summary>
    ///<param name="thumbnail"> Hình thu nhỏ của hình ảnh gốc.</param>
    ///<returns> Kết quả tạo hình thu nhỏ đã lọc.</returns>
    private static FilterThumbnailResult ApplyGrayFilter(Bitmap thumbnail)
    {
    ...
    }

    ///<summary>
    /// Áp dụng bộ lọc phủ định cho hình thu nhỏ.
    ///</summary>
    ///<param name="thumbnail"> Hình thu nhỏ của hình ảnh gốc.</param>
    ///<returns> Kết quả tạo hình thu nhỏ đã lọc.</returns>
    private static FilterThumbnailResult ApplyNegativeFilter(Bitmap thumbnail)
    {
    ...
    }

    ///<summary>
    /// Áp dụng bộ lọc màu nâu đỏ cho hình thu nhỏ.
    ///</summary>
    ///<param name="thumbnail"> Hình thu nhỏ của hình ảnh gốc.</param>
    ///<returns> Kết quả tạo hình thu nhỏ đã lọc.</returns>
    private static FilterThumbnailResult ApplySepiaFilter(Bitmap thumbnail)
    {
    ...
    }
}

Mã sẽ hoạt động tốt nhưng nó có một nhược điểm - nó tạo ra tất cả các hình thu nhỏ một cách tuần tự. Thư viện System.Drawing dựa trên thư viện GDI + khá cũ được thiết kế dưới dạng thư viện luồng đơn nên nó có thể lãng phí tài nguyên khi có nhiều lõi CPU.

Sử dụng Aspose.Drawing có thể giúp cải thiện đáng kể hiệu suất vì nó không có bất kỳ hạn chế nào liên quan đến luồng đơn. Vui lòng thử chỉ thay đổi một chức năng:

///<summary>
/// Tạo một tập hợp các hình thu nhỏ cho tất cả các bộ lọc có sẵn.
///</summary>
///<param name="sourceImage"> Số byte của hình ảnh nguồn.</param>
///<param name="width"> Chiều rộng yêu cầu của hình ảnh xem trước.</param>
///<param name="height"> Chiều cao yêu cầu của hình ảnh xem trước.</param>
///<returns> Một tập hợp các hình thu nhỏ.</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;
    }
}

Mã này hiện có thể sử dụng nhiều lõi CPU mà không có bất kỳ thay đổi đáng kể nào trong mã nguồn ban đầu. Thay thế System.Drawing bằng Aspose.Drawing đẩy nhanh hiệu suất của các ứng dụng và dịch vụ của bạn.

Tải xuống mã nguồn

Bạn có thể tải xuống Mã nguồn liên quan đến ví dụ này để tham khảo.

Giấy phép đánh giá API miễn phí

Bạn có thể yêu cầu Giấy phép tạm thời miễn phí để kiểm tra API trong toàn bộ khả năng của nó.

Sự kết luận

Tóm lại, bạn đã học được với ví dụ rằng việc sử dụng thư viện Aspose.Drawing trong các dịch vụ ASP.NET và ASP.NET Core của bạn đơn giản như thế nào. Hơn nữa, Aspose.Drawing không có vấn đề hoặc phụ thuộc bên ngoài nào tồn tại trong System.Drawing. Hơn nữa, bạn có thể khám phá API một cách chi tiết bằng cách xem qua Tài liệu. Vui lòng liên hệ với chúng tôi bất cứ lúc nào qua Diễn đàn hỗ trợ miễn phí nếu bạn có bất kỳ thắc mắc nào!

Xem thêm