dotnet 控制檯 使用 Microsoft.Maui.Graphics 配合 Skia 進行繪圖入門

lindexi發表於2022-07-01

本文將告訴大家如何在 dotnet 的控制檯模式下,採用 MAUI 自繪庫 Microsoft.Maui.Graphics 進行繪圖,設定 Microsoft.Maui.Graphics 底層呼叫 Microsoft.Maui.Graphics.Skia 庫的 Skia 進行具體的繪圖實現,此控制檯可以跨平臺執行,我在本機 Win10 和 WSL 的 Ubuntu 上都執行過,輸出的結果圖片畫素級相似。本文將告訴大家如何採用 Microsoft.Maui.Graphics 進行跨平臺的自繪

在開始之前,先理清一下概念。剛正式釋出的 MAUI 指的是一個跨平臺的 UI 框架,而 dotnet 指的是在 UI 框架下面的執行時,這是早已實現跨平臺的了。本文所說的 Microsoft.Maui.Graphics 是屬於 MAUI 的一個元件,是 MAUI 的渲染層裡面的一個部分。相當於直接使用 Microsoft.Maui.Graphics 就是將 MAUI 的渲染裡面的一個模組拆出來獨立使用。可以看到 MAUI 的設計上,渲染的一個模組是可以拆處理獨立使用的

本文將從一個控制檯開始,從比較基礎的層面告訴大家如何使用 Microsoft.Maui.Graphics 進行繪圖。我採用 Microsoft.Maui.Graphics.Skia 庫的 Skia 進行具體的繪圖實現,實現將畫出的內容存放到本地檔案

新建一個控制檯專案,我將專案放在 D:\lindexi\Code\SkiaSharp\SkiaSharp\BihuwelcairkiDelalurnere 資料夾裡面

按照慣例,安裝 Microsoft.Maui.Graphics.Skia 的 NuGet 包。為了可以在 Windows Subsystem for Linux (WSL)適用於 Linux 的 Windows 子系統上的 Ubuntu 上執行,繼續新增 SkiaSharp.NativeAssets.Linux.NoDependencies 庫,詳細請看 dotnet 修復在 Linux 上使用 SkiaSharp 提示找不到 liblibSkiaSharp 庫

新增完成庫的 csproj 專案檔案內容如下

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net6.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.Maui.Graphics.Skia" Version="6.0.403" />
    <PackageReference Include="SkiaSharp.NativeAssets.Linux.NoDependencies" Version="2.88.0" />
  </ItemGroup>

</Project>

在 Program.cs 加上名稱空間引用

using Microsoft.Maui.Graphics;
using Microsoft.Maui.Graphics.Skia;
using SkiaSharp;

在 Microsoft.Maui.Graphics 裡,一切的邏輯都是從 ICanvas 畫板開始。這是一個介面,可以採用 SkiaCanvas 來進行實現,程式碼如下

        var skiaCanvas = new SkiaCanvas();

而 SkiaCanvas 需要有一個具體的 Skia 繪製的畫板,也就是 Canvas 屬性。接下來開始構建 Skia 的畫板,採用的是圖片的方式,讓 Skia 繪製到圖片上

先新建圖片的資訊

var skImageInfo = new SKImageInfo(1920, 1080, SKColorType.Bgra8888, SKAlphaType.Opaque, SKColorSpace.CreateSrgb());

我喜歡配置顏色採用 Bgra8888 的格式。在通用性上來說,這個 Bgra8888 是 B(Blue藍色) G(Green綠色) R(Red 紅色) 和 A(Alpha透明度) 每個分量各 8 個位的 32 位表示一個畫素的格式,由於足夠簡單,被很多個平臺和框架和硬體所支援。儘管 Bgra8888 不是效率最高的方式,但好在簡單也方便理解,同時也在多個平臺可以方便共用,因此在不確定選什麼顏色的時候,預設採用這個格式也是不錯的

通過 SKImage.Create 方法建立出圖片,這個圖片不是隻存放磁碟裡的圖片,而是 Skia 的一個概念

using var skImage = SKImage.Create(skImageInfo);

為了在此 SKImage 上繪製,需要取出 SKBitmap 物件,放入到 SKCanvas 裡,程式碼如下

using (SKBitmap skBitmap = SKBitmap.FromImage(skImage))
{
    using (var skCanvas = new SKCanvas(skBitmap))
    {
    }
}

於是就獲取到了 SKCanvas 的物件,可以放入到 SkiaCanvas 裡面

using (SKBitmap skBitmap = SKBitmap.FromImage(skImage))
{
    using (var skCanvas = new SKCanvas(skBitmap))
    {
        var skiaCanvas = new SkiaCanvas();
        skiaCanvas.Canvas = skCanvas;
    }
}

如此即可拿到 ICanvas 的物件,這一層就是抽象的,無論具體的底層繪製採用的是什麼基礎,業務用 ICanvas 型別

        var skiaCanvas = new SkiaCanvas();
        skiaCanvas.Canvas = skCanvas;

        ICanvas canvas = skiaCanvas;

以上就完成了將 Microsoft.Maui.Graphics 的具體繪製底層邏輯更換使用為 Skia 進行繪製。相似的可以替換為採用 WPF 進行繪製,詳細請看 WPF 使用 MAUI 的自繪製邏輯

接下來就是嘗試畫一條線段測試一下

        canvas.StrokeSize = 2;
        canvas.StrokeColor = Colors.Blue;

        canvas.DrawLine(10, 10, 100, 10);

將畫出的內容儲存到圖片檔案,就需要回到 SkiaSharp 的邏輯

        var fileName = $"xx.png";

        skCanvas.Flush();

        using (var skData = skBitmap.Encode(SKEncodedImageFormat.Png, 100))
        {
            var file = new FileInfo(fileName);
            using (var fileStream = file.OpenWrite())
            {
                fileStream.SetLength(0);
                skData.SaveTo(fileStream);
            }
        }

完成程式碼,先在 Windows 上執行一下,可以看到輸出了圖片如下

接下來進入 WLS 也執行一下程式碼

輸出的圖片和在 Windows 上輸出的圖片檔案是完全二進位制相同的

更多細節請看 繪製圖形物件 - .NET MAUI Microsoft Docs

更多的 MAUI 相關部落格,還請參閱我的 部落格導航

本文的例子放在githubgitee 歡迎訪問

可以通過如下方式獲取本文的原始碼,先建立一個空資料夾,接著使用命令列 cd 命令進入此空資料夾,在命令列裡面輸入以下程式碼,即可獲取到本文的程式碼

git init
git remote add origin https://gitee.com/lindexi/lindexi_gd.git
git pull origin d910685120d0a4be91792685ada4bd9c967f6e4a

以上使用的是 gitee 的源,如果 gitee 不能訪問,請替換為 github 的源。請在命令列繼續輸入以下程式碼

git remote remove origin
git remote add origin https://github.com/lindexi/lindexi_gd.git
git pull origin d910685120d0a4be91792685ada4bd9c967f6e4a

獲取程式碼之後,進入 SkiaSharp\BihuwelcairkiDelalurnere 資料夾

我建立了一個 SkiaSharp 的群: 788018852 歡迎大家加入討論

相關文章