Maui.CSharpMath.SkiaSharp Canvas 尝试绘制太大的位图

问题描述 投票:0回答:1

我正在使用 Maui 和库 CSharpMath.SkiaSharp 和 MathPainter 从那里也创建乳胶公式。我有一个编辑器,用户可以在其中输入乳胶。使用MathPainter,我将乳胶公式绘制为流,并用图片实时展示给用户,只要公式改变,这张图片的来源就会改变。它看起来像这样:

MathPainter mathPainter = new() {FontSize = 25};

private void EditorTextChanged(object sender, EventArgs e)
{
   string formula = e.NewTextValue;
   mathPainter.LaTeX = formula;
   LatexImage.Source = ImageSource.FromStream(() => mathPainter.DrawAsStream())
}

然后,当用户完成并单击按钮时,我再次以流形式获取图片并将其保存在我需要的位置。有时它会按预期工作,但大多数时候我只是收到“画布试图绘制太大的位图”异常并且应用程序崩溃。我该如何解决这个问题?

maui android-canvas android-bitmap skiasharp
1个回答
0
投票

好的,我们开始吧:

这是DrawAsStream的源代码:

public static System.IO.Stream? DrawAsStream<TContent>
  (this Painter<SKCanvas, TContent, SKColor> painter,
   float textPainterCanvasWidth = TextPainter.DefaultCanvasWidth,
   TextAlignment alignment = TextAlignment.TopLeft,
   SKEncodedImageFormat format = SKEncodedImageFormat.Png,
   int quality = 100) where TContent : class {
  var size = painter.Measure(textPainterCanvasWidth).Size;
  // SKSurface does not support zero width/height. Null will be returned from SKSurface.Create.
  if (size.Width is 0) size.Width = 1;
  if (size.Height is 0) size.Height = 1;
  using var surface = SKSurface.Create(new SKImageInfo((int)size.Width, (int)size.Height));
  painter.Draw(surface.Canvas, alignment);
  using var snapshot = surface.Snapshot();
  return snapshot.Encode(format, quality).AsStream();
}

这行在这里:

var size = painter.Measure(textPainterCanvasWidth).Size;

一遍又一遍地返回相同的结果。 (此文本PainterCanvasWidth 表示“未使用”)

那么,我们该怎么办? 我们复制这个方法并编写我们自己的:

Stream GetStream(MathPainter painter)
{
    var size = painter.Measure(100).Size; //This returns the same
    size.Width = 300;
    size.Height = 300;
    if (size.Width is 0) size.Width = 1;
    if (size.Height is 0) size.Height = 1;
    using var surface = SKSurface.Create(new SKImageInfo((int)size.Width, (int)size.Height));
    painter.Draw(surface.Canvas, CSharpMath.Rendering.FrontEnd.TextAlignment.Center);
    using var snapshot = surface.Snapshot();
    return snapshot.Encode(SKEncodedImageFormat.Png, 100).AsStream();
}

并将其中的宽度和高度覆盖为 300。

在 XAML 中我们有:

<Image x:Name="myImage" Aspect="AspectFit" WidthRequest="500" HeightRequest="500"/>

在代码中:

myImage.Source = ImageSource.FromStream(() => GetStream(mathPainter));

它或多或少对我有用。

© www.soinside.com 2019 - 2024. All rights reserved.