zoukankan      html  css  js  c++  java
  • SkiaSharp跨平台绘图研究5Blazor WebAssembly网页绘图

    SkiaSharp跨平台绘图研究5-Blazor WebAssembly网页绘图

    20211012日,.NET 6发布RC2候选版本(正式发布前最后一版),宣布了一个突破性的技术:支持在Web网页上采用SkiaSharp画布绘图。这是.NET跨平台技术发展的一个创举,使用C#可以直接在网页画布上绘图,打破了JavaScript+canvas的长期垄断地位。C#是强类型语言,可以无缝对接从服务端获取的结构化数据,有效提高开发效率和质量。

    ASP.NET Core updates in .NET 6 Release Candidate 2 - ASP.NET Blog (microsoft.com)

    SkiaSharp is a cross-platform 2D graphics library for .NET based on the native Skia graphics library, and it now has preview support for Blazor WebAssembly. Let’s give it a try!

    目前VS2022正式版和NET 6正式版都已经发布,SkiaSharpBlazor WebAssembly的支持仍然处于预览状态。

    创建Blazor WebAssembly项目

    选择项目类型Blazor WebAssemblyNET 6.0平台,带托管主机,我是习惯了容器化部署方式,有个后台服务器部署起来顺手一点。

    修改服务端项目program.cs,绑定端口和域名证书。

    using Microsoft.AspNetCore.ResponseCompression;
    using Microsoft.AspNetCore.Server.Kestrel.Core;
    using System.Net;
    
    namespace WebBlazorDemo.Server;
    
    public class Program
    {
        public static async Task Main(string[] args)
        {
            var builder = WebApplication.CreateBuilder(args);
    
            builder.WebHost.ConfigureKestrel(ConfigHttps);
    
            // Add services to the container.
    
            builder.Services.AddControllersWithViews();
            builder.Services.AddRazorPages();
    
            var app = builder.Build();
    
            // Configure the HTTP request pipeline.
            if (app.Environment.IsDevelopment())
            {
                app.UseWebAssemblyDebugging();
            }
            else
            {
                app.UseExceptionHandler("/Error");
            }
    
            app.UseBlazorFrameworkFiles();
            app.UseStaticFiles();
    
            app.UseRouting();
    
    
            app.MapRazorPages();
            app.MapControllers();
            app.MapFallbackToFile("index.html");
    
            //app.Run();
            await app.RunAsync();
        }
    
        private static void ConfigHttps(WebHostBuilderContext context, KestrelServerOptions options)
        {
            //http服务端口
            options.Listen(IPAddress.Any, 7902);
    
            //https服务端口
            options.Listen(IPAddress.Any, 7903, configure);
    
            void configure(ListenOptions listenOptions)
            {
                if (context.HostingEnvironment.IsProduction())
                {
                    //填入pfx文件路径和指定的密码
                    listenOptions.UseHttps("myweb.pfx", "xxx");
                }
                else
                {
                    //本机调试必须采用默认localhost证书,否则无法建立ssl连接
                    listenOptions.UseHttps();
                }
            }
        }
    }

    给客户端项目NuGet安装SkiaSharp.Views.Blazor,现在最新版是2.88.0-preview.155

    给主页添加绘图代码,跟WPF基本一样。

    @page "/"
    @using SkiaSharp.Views.Blazor
    @using SkiaSharp
    
    <PageTitle>Index</PageTitle>
    
    <h1>Hello, world!</h1>
    
    Welcome to your new app.
    
    <SurveyPrompt Title="How is Blazor working for you?" />
    
    <button class="btn btn-primary m-1" @onclick="OnClickImg" type="button">更新绘图</button>
    <br />
    
    <SKCanvasView OnPaintSurface="OnPaintSurface" style="480px; height:240px" @ref="canvasView" @onclick="OnClickImg" />
    
    @code {
    
        //private ElementReference canvasView;//这个参数无法转换类型为SKCanvasView
        private SKCanvasView canvasView;
    
        private void OnClickImg()
        {
            //引发画布更新绘图
            canvasView.Invalidate();
        }
    
        void OnPaintSurface(SKPaintSurfaceEventArgs e)
        {
            var canvas = e.Surface.Canvas;
    
            canvas.Clear(SKColors.SkyBlue);
    
            using var paint = new SKPaint
                {
                    Color = SKColors.Black,
                    IsAntialias = true,
                    Typeface = SkiaChinaFont.ChinaFont,
                    TextSize = 24
                };
    
            string msg = $"{DateTimeOffset.Now:T}, 还有1万行Skia绘图代码...";
            canvas.DrawText(msg, 0, 30, paint);
    
            using var linePaint = new SKPaint()
                {
                    Color = (DateTimeOffset.Now.Second % 4 <= 1) ? SKColors.Red : SKColors.Green,
                    Style = SKPaintStyle.Stroke,//不填充
                    StrokeWidth = 3,
                };
            canvas.DrawRect(10, 50, e.Info.Width - 20, e.Info.Height - 60, linePaint);
    
            msg += $", linePaint.Color={linePaint.Color}, skContainer.CanvasSize={e.Info.Size}";
            Console.WriteLine(msg);
    
        }
    }

    同样要添加中文字体类,注意要设置字体文件为嵌入的资源。

    using SkiaSharp;
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Reflection;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace WebBlazorDemo.Client;
    
    /// <summary>
    /// Skia中文字体
    /// </summary>
    public static class SkiaChinaFont
    {
        public static SKTypeface ChinaFont { get; private set; }
    
        static SkiaChinaFont()
        {
            //加载资源方案,设置字体文件属性为嵌入的资源
            var fontStream = Assembly.GetExecutingAssembly().GetManifestResourceStream("WebBlazorDemo.Client.DroidSansFallback.ttf");
            ChinaFont = SKTypeface.FromStream(fontStream);
        }
    }

    我在安装VS2022的时候没有添加wasm-tools工作负载,所以会编译Blazor WebAssembly报错,在命令行运行dotnet workload install wasm-tools即可添加。然后跑起来看一下,如愿以偿!在网页上用C#绘图,终于等到了。

     

    发布服务端项目到腾讯云CentOS操作系统容器里测试,跟本机测试一样结果,没有什么依赖库。

    展望

    网页前端开发主要就是Html + Css + JavaScript三板斧,基于三板斧不断封装也发展出了ReactVueAngular等集成框架,但是前后端数据交互通常要做很多变换处理,毕竟前后端语言的数据类型不一样。Blazor框架把C#强类型语言推进到前端网页开发,打通了前后端统一框架和语言的技术路线,这是非常了不起的突破。Blazor开发常规的表单、导航网页功能都已经非常好用了,但是一旦涉及绘图,仍然要借助JavaScript语言去实现,实在是一个遗憾。

    不过从现在开始,C#也可以在Html网页SkiaSharp画布上绘图了,消除了C#前端开发最后一个屏障。但是,仅有绘图功能是远远不够的,Html生态圈中有海量高质量、开源的图形插件,例如ECharts,把模板选好,再放入数据,就能出来光鲜亮丽的图表,并且拥有非常丰富的滚动,缩放,悬停,选取等交互能力。SkiaSharp画布要走的路还很长,希望将来能构建起一个新的生态圈。

    DEMO源代码参见:https://gitee.com/woodsun/skia-sharp-demo

  • 相关阅读:
    复利软件单利及期望值的实现
    实验0 了解和熟悉操作系统
    关于《软件工程》的读后感
    评论
    一个完整的大作业
    数据结构化与保存
    爬取所有校园新闻
    用requests库和BeautifulSoup4库爬取新闻列表
    中文词频统计及词云制作
    组合数据类型练习,英文词频统计实例
  • 原文地址:https://www.cnblogs.com/sunnytrudeau/p/15574467.html
Copyright © 2011-2022 走看看