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

来源:https://www.cnblogs.com/lindexi/archive/2022/07/01/16433320.html
-Advertisement-
Play Games

進入移動互聯網時代以來,Windows桌面開發已經很久不碰了。之前就是從做Windows開發入行的。 當年,還是C++ VC6, MFC的時代。那時候開發要查的是MSDN :-)。記憶體要自己管理, 排查記憶體泄漏(忘了釋放分配的記憶體)也是基本日常。光陰似箭,歲月如梭~! 幾年之前,北漂時需要寫一個wi ...


本文將告訴大家如何在 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 歡迎大家加入討論

博客園博客只做備份,博客發佈就不再更新,如果想看最新博客,請到 https://blog.lindexi.com/

知識共用許可協議
本作品採用知識共用署名-非商業性使用-相同方式共用 4.0 國際許可協議進行許可。歡迎轉載、使用、重新發佈,但務必保留文章署名[林德熙](http://blog.csdn.net/lindexi_gd)(包含鏈接:http://blog.csdn.net/lindexi_gd ),不得用於商業目的,基於本文修改後的作品務必以相同的許可發佈。如有任何疑問,請與我[聯繫](mailto:[email protected])。
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 前言 嗨嘍,大家好呀,這裡是魔王~ 我們空閑時都會聽聽音樂,放鬆一下自己的心情,每個人都會有自己喜歡的歌手或歌 但是通常一個平臺不能完全找到,因為版權原因,經常需要幾個軟體跨著聽,非常的麻煩 那麼現在,我們直接來用代碼全部下載下來用本地播放器播放,美滋滋! 開發環境: 版 本:python3.8 編 ...
  • 一、from + size 淺分頁 "淺"分頁可以理解為簡單意義上的分頁。 它的原理很簡單,就是查詢前20條數據,然後截斷前10條,只返回10-20的數據。這樣其實白白浪費了前10條的查詢。 GET test_dev/_search { "query": { "bool": { "filter": ...
  • 1.先決條件 無論什麼方式安裝,都需要先初始化資料庫,這裡我選擇了在本地通過 Docker 啟用一個 mysql 5.7 docker run -d \ --name mysql \ -p 3306:3306 \ -e MYSQL_ROOT_PASSWORD=xyzj1a2y3 \ -e TZ=As ...
  • 這幾年,隨著幾大互聯網公司的強大,紛紛投入雲計算產業的建設,開源項目作為維護潛在客戶群體(開發者)的重要手段,是各大雲計算廠商都在努力做的事。 這幾年也誕生了很多真正優秀和看似優秀的開源項目。真正優秀的不必多說,就是那些被真實廣泛應用的開源項目,而今天我想說的是那些看似優秀的開源項目。 為什麼有些項 ...
  • 案例來源 https://github.com/apache/flink-training/blob/release-1.14/hourly-tips/README_zh.md 案例介紹 基於計程車付費事件流計算出每小時賺取最多小費的司機,最簡單的方法是通過兩個步驟來解決這個問題:首先使用一個小時長 ...
  • 一:背景 1. 講故事 前段時間有位朋友在微信上找到我,說他的 web 系統 cpu 運行一段時候後就爆高了,讓我幫忙看一下是怎麼回事,那就看吧,聲明一下,我看 dump 是免費的,主要是錘煉自己技術,沒有某軟工程師高額的技術分析費。 😅😅😅 閑話不多說,我們上 windbg 說話。 二:Wi ...
  • 【微服務專題之】.Net6下集成消息隊列上-RabbitMQ ...
  • 最基礎的:UI-BLL-DAL 這是我們耳熟能詳的分層 (補充:) 我們的類正常都不是孤立存在的。很多都是要依賴於其它的類。 比如說我們有一個Work類,Work類在工作的時候需要把信息記錄下來。 MessageWriter就是 Worker的依賴項 首先我聽到依賴註入之後看似非常的複雜 實際則是: ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...