我正在使用 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())
}
然后,当用户完成并单击按钮时,我再次以流形式获取图片并将其保存在我需要的位置。有时它会按预期工作,但大多数时候我只是收到“画布试图绘制太大的位图”异常并且应用程序崩溃。我该如何解决这个问题?
好的,我们开始吧:
这是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));
它或多或少对我有用。