C# Bitmap Library to Replace System.Drawing.Com/mon in .NET

This article was translated from English: Does it need improvement?
Translated
View the article in English

IronDrawing 是一款免費的開源軟體,並支援大多數 .NET 繪圖函式庫格式

IronDrawing 是由 Iron Software 最初開發的開源函式庫,可協助 C# 軟體工程師在 Windows、macOS 和 Linux 平台的 .NET 專案中替換 System.Drawing.Com/mon

開發支援圖形、影像和字型的 .NET 5、6、7 及 8 類別函式庫與 NuGet 套件 理應 相當容易。

隨著 .NET 5、6、7 及 8 所有新提案的圖形標準不斷演進,IronDrawing 將作為這些標準之間的無縫橋樑——因此您只需針對您偏好的標準進行開發即可。

IronDrawing 是一款免費的開源軟體,並支援大多數 .NET 繪圖函式庫格式

上下文

Microsoft .NET Framework 是一個跨平台且高度相容的軟體框架,全球數百萬名軟體開發人員皆在使用。 微軟已宣布一項重大變更,即 System.Drawing.Com/mon 僅會在 Windows 平台上受到支援。

這對維護使用 System.Drawing.Com/mon 的跨平台 .NET 函式庫開發者而言是個難題,因為微軟建議的解決方案要求您必須重新編譯函式庫,才能支援非 Windows 使用者。 預期志工與學術界人士將必須重新建置每個 NuGet 套件與類別庫,以採用隨之推出的各項新建議圖形函式庫,這將造成技術負債,進而延緩現代 .NET 的採用進程。

歸根結底,當我們使用 .NET 時,我們就使用 NuGet。

NuGet 套件開發者透過推動 .NET 技術及預先封裝的程式碼,為我們所有人提供了莫大幫助——這些程式碼若由我們自行編寫,每天將耗費數千小時。

重大變更將延緩 NuGet 的開發進度,並可能導致 .NET 開發人員所依賴的程式庫遭棄用或過時。 我們必須立即採取行動!

我們的解決方案

一種用於在所有舊版與新版圖形函式庫之間進行轉換的中介圖形格式。

身為類別庫開發者,您的公開 Font 以及 Size 輸入與輸出只能採用單一類型,且該類型須支援所有新標準。 內部操作方面,您可以繼續按照慣例進行。

IronDrawing 向下相容於 .NET Framework 4.62,並支援所有版本的 .NET(包括 .NET 8)。

IronDrawing 的開發與發布透過提供開源解決方案,解決了重要類別(例如 FontSize 等重要類別缺乏統一格式之問題。 IronSoftware.Drawing 將為您在 SkiaSharpSixLabors 之間,無縫轉換這些類型的實作。 這讓您(開發者)無需在您的程式庫中替換所有這些類別的實例。

例如,若您正在使用 System.Drawing.Bitmap,可使用 IronDrawing 的 AnyBitmap 類別,該類別具備對以下任一類型的隱含轉換:Microsoft.Maui.Graphics.Platform.PlatformImage

為何我們要免費提供這項服務

我們開發 IronDrawing 的初衷,源於 Iron Software 的成員皆為資深且長期投身於 .NET 開發的工程師,我們關注 .NET 的演進,並期盼它能持續成長與成功。 我們很高興看到 .NET 持續成長與演進,例如 .NET 7 的推出。我們整天都在使用 NuGet,相信您也是如此。 我們支持並希望鼓勵大家順利過渡至未來,逐步淘汰 System.Drawing

我們致力於簡化所有 .NET 類別庫與 NuGet 的開發流程,讓 NuGet 生態系統持續蓬勃發展,使所有 .NET 開發者都能從中受益。

IronSoftware.Drawing 功能

  • AnyBitmap:一個通用相容的 Bitmap 類別。 IronSoftware.Drawing.AnyBitmap 與以下內容之間的隱式轉換受支援:
    • System.Drawing.Bitmap
    • System.Drawing.Image
    • SkiaSharp.SKBitmap
    • SkiaSharp.SKImage
    • SixLabors.ImageSharp
    • Microsoft.Maui.Graphics.Platform.PlatformImage
  • Color:一個普遍相容的 Color 類別。 IronSoftware.Drawing.Co/lor 與以下內容之間的隱含型別轉換受支援:
    • System.Drawing.Co/lor
    • SkiaSharp.SKColor
    • SixLabors.ImageSharp.Co/lor
    • SixLabors.ImageSharp.PixelFormats
  • Rectangle:一個普遍相容的 Rectangle 類別。 IronSoftware.Drawing.Rectangle 與以下內容之間的隱含型別轉換受支援:
    • System.Drawing.Rectangle
    • SkiaSharp.SKRect
    • SkiaSharp.SKRectI
    • SixLabors.ImageSharp.Rectangle
  • Font:一個普遍相容的 Font 類別。 IronSoftware.Drawing.Font 與以下內容之間的隱式轉換受支援:
    • System.Drawing.Font
    • SkiaSharp.SKFont
    • SixLabors.Fonts.Font

相容性

IronSoftware.Drawing 具備以下平台的跨平台相容性:

  • .NET 8、.NET 7、.NET 6、.NET 5、.NET Core、.NET Standard 以及 .NET Framework 4.62+
  • Windows、macOS、Linux、Docker、Azure 及 AWS

安裝

安裝 IronDrawing (IronSoftware.Drawing) NuGet 套件既快速又簡單。 請按照以下方式安裝此套件:

Install-Package IronSoftware.System.Drawing

您亦可直接從官方 NuGet 網站下載。

安裝完成後,您只需在 C# 程式碼開頭加入 using IronSoftware.Drawing; 即可開始使用。

程式碼範例

AnyBitmap 範例

:path=/static-assets/drawing/content-code-examples/get-started/anybitmap.cs
using IronSoftware.Drawing;
using System.IO;
using System.Drawing;

// Create a new AnyBitmap object from a file
// Replace "FILE_PATH" with the actual path of the image you want to process
var bitmap = AnyBitmap.FromFile("FILE_PATH");

// Save the AnyBitmap object as a JPEG file
bitmap.SaveAs("result.jpg");

// Export the AnyBitmap as a byte array
// This can be useful if you want to send the image data over a network or save it in a database
var bytes = bitmap.ExportBytes();

// Create a memory stream to export the AnyBitmap as a JPEG stream with 100% quality
using (var resultExport = new MemoryStream())
{
    // This exports the image to the stream with the specified format and quality
    bitmap.ExportStream(resultExport, AnyBitmap.ImageFormat.Jpeg, 100);
    // Be sure to use 'using' or manually close the stream to release resources
}

// Casting between System.Drawing.Bitmap and IronSoftware.Drawing.AnyBitmap
// Load a System.Drawing.Bitmap from the same file
System.Drawing.Bitmap image = new System.Drawing.Bitmap("FILE_PATH");

// This is an implicit conversion from System.Drawing.Bitmap to IronSoftware.Drawing.AnyBitmap
// This step is necessary if you are working with System.Drawing.Bitmap and need to convert to IronSoftware.Drawing.AnyBitmap for processing
IronSoftware.Drawing.AnyBitmap anyBitmap = AnyBitmap.FromBitmap(image);

// Save the resulting AnyBitmap from casting as a PNG file
anyBitmap.SaveAs("result-from-casting.png");
Imports IronSoftware.Drawing
Imports System.IO
Imports System.Drawing

' Create a new AnyBitmap object from a file
' Replace "FILE_PATH" with the actual path of the image you want to process
Private bitmap = AnyBitmap.FromFile("FILE_PATH")

' Save the AnyBitmap object as a JPEG file
bitmap.SaveAs("result.jpg")

' Export the AnyBitmap as a byte array
' This can be useful if you want to send the image data over a network or save it in a database
Dim bytes = bitmap.ExportBytes()

' Create a memory stream to export the AnyBitmap as a JPEG stream with 100% quality
Using resultExport = New MemoryStream()
	' This exports the image to the stream with the specified format and quality
	bitmap.ExportStream(resultExport, AnyBitmap.ImageFormat.Jpeg, 100)
	' Be sure to use 'using' or manually close the stream to release resources
End Using

' Casting between System.Drawing.Bitmap and IronSoftware.Drawing.AnyBitmap
' Load a System.Drawing.Bitmap from the same file
Dim image As New System.Drawing.Bitmap("FILE_PATH")

' This is an implicit conversion from System.Drawing.Bitmap to IronSoftware.Drawing.AnyBitmap
' This step is necessary if you are working with System.Drawing.Bitmap and need to convert to IronSoftware.Drawing.AnyBitmap for processing
Dim anyBitmap As IronSoftware.Drawing.AnyBitmap = AnyBitmap.FromBitmap(image)

' Save the resulting AnyBitmap from casting as a PNG file
anyBitmap.SaveAs("result-from-casting.png")
$vbLabelText   $csharpLabel

顏色範例

:path=/static-assets/drawing/content-code-examples/get-started/color.cs
using IronSoftware.Drawing;
using System;

// The IronSoftware.Drawing library provides enhanced color manipulation features.
// This example demonstrates creating color objects and converting between
// System.Drawing.Color and IronSoftware.Drawing.Color.

// Create a new Color object from a hex string.
Color fromHex = Color.FromHex("#191919");

// Create a new Color object from RGB values.
Color fromRgb = Color.FromRgb(255, 255, 0);

// Create a new Color object using an enumeration.
Color fromEnum = Color.Crimson;

// Casting between System.Drawing.Color and IronSoftware.Drawing.Color.
System.Drawing.Color drawingColor = System.Drawing.Color.Red;

// Convert System.Drawing.Color to IronSoftware.Drawing.Color.
IronSoftware.Drawing.Color ironColor = Color.FromSystemColor(drawingColor);

// Access the alpha, red, green, and blue components of the IronSoftware.Drawing.Color.
byte alpha = ironColor.A;
byte red = ironColor.R;
byte green = ironColor.G;
byte blue = ironColor.B;

// Calculate the luminance of the color.
// Luminance is a value from 0 (black) to 100 (white) where 50 is the perceptual "middle grey".
double luminance = ironColor.GetLuminance();

// Log the calculated attributes to the console.
Console.WriteLine($"Color Details - ARGB: ({alpha}, {red}, {green}, {blue}), Luminance: {luminance}");
Imports IronSoftware.Drawing
Imports System

' The IronSoftware.Drawing library provides enhanced color manipulation features.
' This example demonstrates creating color objects and converting between
' System.Drawing.Color and IronSoftware.Drawing.Color.

' Create a new Color object from a hex string.
Private fromHex As Color = Color.FromHex("#191919")

' Create a new Color object from RGB values.
Private fromRgb As Color = Color.FromRgb(255, 255, 0)

' Create a new Color object using an enumeration.
Private fromEnum As Color = Color.Crimson

' Casting between System.Drawing.Color and IronSoftware.Drawing.Color.
Private drawingColor As System.Drawing.Color = System.Drawing.Color.Red

' Convert System.Drawing.Color to IronSoftware.Drawing.Color.
Private ironColor As IronSoftware.Drawing.Color = Color.FromSystemColor(drawingColor)

' Access the alpha, red, green, and blue components of the IronSoftware.Drawing.Color.
Private alpha As Byte = ironColor.A
Private red As Byte = ironColor.R
Private green As Byte = ironColor.G
Private blue As Byte = ironColor.B

' Calculate the luminance of the color.
' Luminance is a value from 0 (black) to 100 (white) where 50 is the perceptual "middle grey".
Private luminance As Double = ironColor.GetLuminance()

' Log the calculated attributes to the console.
Console.WriteLine($"Color Details - ARGB: ({alpha}, {red}, {green}, {blue}), Luminance: {luminance}")
$vbLabelText   $csharpLabel

矩形範例

:path=/static-assets/drawing/content-code-examples/get-started/rectangle.cs
using IronSoftware.Drawing;
using System.Drawing;

// Declare an IronSoftware.Drawing.Rectangle object
IronSoftware.Drawing.Rectangle ironRectangle = new IronSoftware.Drawing.Rectangle(5, 5, 50, 50);

// Declare a System.Drawing.Rectangle object
System.Drawing.Rectangle systemRectangle = new System.Drawing.Rectangle(10, 10, 150, 150);

// Implicitly convert System.Drawing.Rectangle to IronSoftware.Drawing.Rectangle
// Note: Uncomment and use appropriate conversion methods if available in the IronSoftware.Drawing library
// ironRectangle = (IronSoftware.Drawing.Rectangle)systemRectangle;

// Output the properties of IronSoftware.Drawing.Rectangle if conversion is successful
// These Console.WriteLine statements assume this code runs in a console environment
Console.WriteLine(ironRectangle.X);
Console.WriteLine(ironRectangle.Y);
Console.WriteLine(ironRectangle.Width);
Console.WriteLine(ironRectangle.Height);
Imports IronSoftware.Drawing
Imports System.Drawing

' Declare an IronSoftware.Drawing.Rectangle object
Private ironRectangle As New IronSoftware.Drawing.Rectangle(5, 5, 50, 50)

' Declare a System.Drawing.Rectangle object
Private systemRectangle As New System.Drawing.Rectangle(10, 10, 150, 150)

' Implicitly convert System.Drawing.Rectangle to IronSoftware.Drawing.Rectangle
' Note: Uncomment and use appropriate conversion methods if available in the IronSoftware.Drawing library
' ironRectangle = (IronSoftware.Drawing.Rectangle)systemRectangle;

' Output the properties of IronSoftware.Drawing.Rectangle if conversion is successful
' These Console.WriteLine statements assume this code runs in a console environment
Console.WriteLine(ironRectangle.X)
Console.WriteLine(ironRectangle.Y)
Console.WriteLine(ironRectangle.Width)
Console.WriteLine(ironRectangle.Height)
$vbLabelText   $csharpLabel

字型範例

:path=/static-assets/drawing/content-code-examples/get-started/font.cs
using System;
using System.Drawing;
using IronSoftware.Drawing;

// Create a new Font object with a specified font family, style, and size
IronSoftware.Drawing.Font font = new IronSoftware.Drawing.Font("Times New Roman", FontStyle.Italic | FontStyle.Bold, 30);

// Create a new instance of System.Drawing.Font
System.Drawing.Font drawingFont = new System.Drawing.Font("Courier New", 30);

try
{
    // Attempt to cast System.Drawing.Font to IronSoftware.Drawing.Font
    // Note: This cast may not be directly possible if the libraries do not support each other;
    // additional conversion logic might be required.
    IronSoftware.Drawing.Font ironFont = new IronSoftware.Drawing.Font(drawingFont.FontFamily.Name, drawingFont.Style, drawingFont.Size);

    // Accessing properties of the IronSoftware.Drawing.Font object
    string familyName = ironFont.FamilyName; // Get the font family name
    FontStyle style = ironFont.Style;       // Get the combined font style (italic, bold, etc.)
    float size = ironFont.Size;             // Get the font size
    bool isItalic = ironFont.Italic;        // Determine if the font style includes Italic
    bool isBold = ironFont.Bold;            // Determine if the font style includes Bold

    // Output the font properties to verify correctness
    Console.WriteLine($"Family: {familyName}, Style: {style}, Size: {size}, Italic: {isItalic}, Bold: {isBold}");
}
catch (InvalidCastException)
{
    Console.WriteLine("The conversion between System.Drawing.Font and IronSoftware.Drawing.Font is not directly supported.");
}
catch (Exception ex)
{
    Console.WriteLine($"An error occurred: {ex.Message}");
}
Imports System
Imports System.Drawing
Imports IronSoftware.Drawing

' Create a new Font object with a specified font family, style, and size
Private font As New IronSoftware.Drawing.Font("Times New Roman", FontStyle.Italic Or FontStyle.Bold, 30)

' Create a new instance of System.Drawing.Font
Private drawingFont As New System.Drawing.Font("Courier New", 30)

Try
	' Attempt to cast System.Drawing.Font to IronSoftware.Drawing.Font
	' Note: This cast may not be directly possible if the libraries do not support each other;
	' additional conversion logic might be required.
	Dim ironFont As New IronSoftware.Drawing.Font(drawingFont.FontFamily.Name, drawingFont.Style, drawingFont.Size)

	' Accessing properties of the IronSoftware.Drawing.Font object
	Dim familyName As String = ironFont.FamilyName ' Get the font family name
	Dim style As FontStyle = ironFont.Style ' Get the combined font style (italic, bold, etc.)
	Dim size As Single = ironFont.Size ' Get the font size
	Dim isItalic As Boolean = ironFont.Italic ' Determine if the font style includes Italic
	Dim isBold As Boolean = ironFont.Bold ' Determine if the font style includes Bold

	' Output the font properties to verify correctness
	Console.WriteLine($"Family: {familyName}, Style: {style}, Size: {size}, Italic: {isItalic}, Bold: {isBold}")
Catch e1 As InvalidCastException
	Console.WriteLine("The conversion between System.Drawing.Font and IronSoftware.Drawing.Font is not directly supported.")
Catch ex As Exception
	Console.WriteLine($"An error occurred: {ex.Message}")
End Try
$vbLabelText   $csharpLabel

提供支援

授權

授權資訊請參閱此處:LICENSE.txt

貢獻

若您有意為 IronDrawing 開源專案貢獻心力,請在向 GitHub 儲存庫提交拉取請求前,先閱讀授權條款

資訊

如需更多關於 Iron Software 的資訊,請造訪我們的網站: https://ironsoftware.com/

Iron Software 提供支援

如需一般支援或技術諮詢,請透過電子郵件聯絡我們: mailto:support@ironsoftware.com/mailto:support@ironsoftware.com

Curtis Chau
技術撰稿人

Curtis Chau 擁有卡爾頓大學(Carleton University)的電腦科學學士學位,專精於前端開發,並精通 Node.js、TypeScript、JavaScript 及 React。他熱衷於打造直觀且美觀的用戶介面,喜歡運用現代框架,並創建結構完善、視覺上吸引人的手冊。

除了開發工作之外,Curtis 對物聯網(IoT)抱有濃厚興趣,致力於探索整合硬體與軟體的創新方法。閒暇時,他喜歡玩遊戲和開發 Discord 機器人,將對科技的熱愛與創意相結合。

準備開始了嗎?
Nuget 下載 16,991,182 | 版本: 2025.3 just released
Still Scrolling Icon

還在往下捲動嗎?

想要快速確認成果嗎? PM > Install-Package IronSoftware.System.Drawing
執行範例 觀看您的 HTML 轉為 PDF。