SkiaSharp跨平台绘图研究3-Asp.Net Core网站
SkiaSharp跨平台绘图研究3-Asp.Net Core网站
新建Asp.Net Core网站项目
新建Asp.Net Core Web(视图-模型-控制器)项目WebMvcDemo。
NuGet安装最新预览版SkiaSharp 2.88.0-preview.155。
在主页上放一个SkiaSharp画布,点击一下可以刷新,这个方案很常见,例如图片验证码。
@{ ViewData["Title"] = "Home Page"; } <div class="text-center"> <h1 class="display-4">Welcome</h1> <p>Learn about <a href="https://docs.microsoft.com/aspnet/core">building Web apps with ASP.NET Core</a>.</p> <h4>SkiaSharp绘图</h4> <button class="btn btn-primary m-1" onclick="OnClickImg()" type="button">更新绘图</button> <br /> <img src="/Home/GetImg" alt="pic" class="img-thumbnail" width="600" height="300" id="imgCaptcha" onclick="OnClickImg()" title="点击图片更新" /> </div> @section Scripts { <script type="text/javascript"> function OnClickImg() { //确保URL每秒有变化,否则浏览器不去访问服务端 var date = new Date(); var src = "/Home/GetImg?id=" + date.getTime(); document.getElementById("imgCaptcha").src = src; } </script> }
后台控制台Action每次新建一个图片文件返回给前端网页,绘图代码跟之前的WPF项目基本类似。字体文件也跟WPF项目那样复制都输出目录。
/// <summary> /// 创建Skia图片 /// </summary> /// <param name="id">前端html设置img的src的id参数变化,可以更新图片</param> /// <returns></returns> public IActionResult GetImg(string id) { _logger.LogInformation($"{DateTime.Now}, 开始创建图片"); //创建画布的容器 var info = new SKImageInfo(600, 300); using var surface = SKSurface.Create(info); var canvas = 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, info.Width - 20, info.Height - 60, linePaint); msg += $", linePaint.Color={linePaint.Color}, skContainer.CanvasSize={info.Size}"; Debug.WriteLine(msg); //把画布容器转换为图片文件 using var image = surface.Snapshot(); using var data = image.Encode(SKEncodedImageFormat.Png, 100); return File(data.ToArray(), "image/png"); }
然后把网站跑起来,可以在浏览器中看到图片,点击图片可以刷新内容。
发布到Linux云服务器测试
把网站发布到本机硬盘目录,打开控制台,运行网站,打开浏览器访问网站,测试没问题,再把发布目录拖到腾讯云CentOS操作系统测试。
在云服务器测试发现,必须绑定正确的域名证书,不然侦听https失败,但是控制台并没有提示https绑定错误信息,并且http侦听端口也是80。绑定域名证书后才能正确侦听指定端口。
skiawebmvc | {"EventId":14,"LogLevel":"Information","Category":"Microsoft.Hosting.Lifetime","Message":"Now listening on: http://0.0.0.0:7900","State":{"Message":"Now listening on: http://0.0.0.0:7900","address":"http://0.0.0.0:7900","{OriginalFormat}":"Now listening on: {address}"}}
skiawebmvc | {"EventId":14,"LogLevel":"Information","Category":"Microsoft.Hosting.Lifetime","Message":"Now listening on: https://0.0.0.0:7901","State":{"Message":"Now listening on: https://0.0.0.0:7901","address":"https://0.0.0.0:7901","{OriginalFormat}":"Now listening on: {address}"}}
打开网站主页,无法显示图片,云服务器控制台显示错误信息:
System.TypeInitializationException: The type initializer for \u0027SkiaSharp.SKImageInfo\u0027 threw an exception. ---\u003E System.DllNotFoundException: Unable to load shared library \u0027libSkiaSharp\u0027 or one of its dependencies. In order to help diagnose loading problems, consider setting the LD_DEBUG environment variable: liblibSkiaSharp: cannot open shared object file: No such file or directory
因为Skia在Linux平台上依赖一个库文件,所以要把这个库文件安装到容器里边,以前我用了一个比较麻烦的方法,去下载libSkiaSharp.so,设置文件属性为复制到输出目录,并修改dockerfile在构建容器时安装依赖库。
RUN echo "deb http://mirrors.aliyun.com/debian wheezy main contrib non-free \
deb-src http://mirrors.aliyun.com/debian wheezy main contrib non-free \
deb http://mirrors.aliyun.com/debian wheezy-updates main contrib non-free \
deb-src http://mirrors.aliyun.com/debian wheezy-updates main contrib non-free \
deb http://mirrors.aliyun.com/debian-security wheezy/updates main contrib non-free \
deb-src http://mirrors.aliyun.com/debian-security wheezy/updates main contrib non-free" > /etc/apt/sources.list
RUN apt-get update && apt-get install libfontconfig1 -y
后来了解到有一个NuGet包SkiaSharp.NativeAssets.Linux.NoDependencies,安装它就可以了,不用修改dockerfile,真是太神奇了。
<PackageReference Include="SkiaSharp.NativeAssets.Linux.NoDependencies" Version="2.88.0-preview.155" />
可以参考这篇文章。
https://www.cnblogs.com/yycelsu/p/14048859.html
《Docker环境下使用SkiaSharp的2种方式 - 从零开始-DotNET技术 - 博客园》
因此dockerfile可以很简单了
FROM mcr.microsoft.com/dotnet/aspnet:6.0 WORKDIR /app COPY . /app #EXPOSE 5000 ENTRYPOINT ["dotnet", "WebMvcDemo.dll"]
Docker compose脚本文件也很简单
version: '3' services: skiawebmvc: container_name: skiawebmvc image: skiawebmvcimage build: context: /home/skiawebmvc/skiawebmvcpub dockerfile: Dockerfile ports: - "7900:7900" - "7901:7901" environment: - ASPNETCORE_ENVIRONMENT=Production #- ASPNETCORE_ENVIRONMENT=Development - TZ=Asia/Shanghai volumes: - ./aspnetkeys:/root/.aspnet/DataProtection-Keys - ./myweb.pfx:/app/myweb.pfx restart: always
再次访问网站,图片出来了。
DEMO源代码参见:https://gitee.com/woodsun/skia-sharp-demo