3

我正在使用 FFImageLoading 在我的 Xamarin.Forms 项目中显示 svg 图标。我的理解是,必须明确设置高度和宽度请求才能正确呈现 SVG。每当我尝试将高度/宽度请求绑定到 ViewModel 上的值时,我都会得到很多像素化(我有这个需求,因为所需的大小取决于数据)。如果我明确设置大小,一切看起来都很好。

每当高度/宽度请求的绑定发生变化时,SvgCachedImage 是否不会重绘 SVG?

如果没有,我有没有办法在大小更改时明确强制它们无效并重绘?

4

2 回答 2

2

通过将水平和垂直选项设置为填充而不是中心来解决模糊问题:

<Grid>
                                <ffimageloadingsvg:SvgCachedImage  BackgroundColor="Transparent"
                                                              Margin="{Binding HarmonicIconMargin}"
                                                              HorizontalOptions="Fill"
                                                              VerticalOptions="Fill"
                                                              WidthRequest="{Binding HarmonicIconWidth}"
                                                              HeightRequest="{Binding HarmonicIconWidth}"
                                                              Source="{Binding CurrentTestItem, Converter={StaticResource TestItemToHarmonicIconConverter}}" />
                            </Grid>

那时它似乎忽略了高度/宽度请求。我可以尝试更多(也许请求是空间太大),但我发现将边距绑定到计算属性有效地使我能够控制 SVG 图像的大小,同时不会导致它变得模糊。

于 2020-03-06T19:17:00.950 回答
0

为了解决缩放视图大小时的svg模糊问题,

  1. 更改SvgImageSource.VectorWidthSvgImageSource.VectorHeight
  2. 重新加载图像
protected override void OnSizeAllocated(double width, double height)
{
    if (0 < width && 0 < height && && Source is SvgImageSource imageSource)
    {
        imageSource.VectorWidth = (int)Math.Ceiling(width);
        imageSource.VectorHeight = (int)Math.Ceiling(height);
        svgImage.ReloadImage();

        base.OnSizeAllocated(width, height);
    }
}

根据FFImageLoading 源代码,SVG 图像大小由SvgImageSource.VectorWidth或决定SvgImageSource.VectorHeight

double sizeX = VectorWidth;
double sizeY = VectorHeight;

if (UseDipUnits)
{
    sizeX = VectorWidth.DpToPixels();
    sizeY = VectorHeight.DpToPixels();
}

if (sizeX <= 0 && sizeY <= 0)
{
    if (picture.CullRect.Width > 0)
        sizeX = picture.CullRect.Width;
    else
        sizeX = 400;

    if (picture.CullRect.Height > 0)
        sizeY = picture.CullRect.Height;
    else
        sizeY = 400;
}
else if (sizeX > 0 && sizeY <= 0)
{
    sizeY = (int)(sizeX / picture.CullRect.Width * picture.CullRect.Height);
}
else if (sizeX <= 0 && sizeY > 0)
{
    sizeX = (int)(sizeY / picture.CullRect.Height * picture.CullRect.Width);
}

resolvedData.ImageInformation.SetType(ImageInformation.ImageType.SVG);

using (var bitmap = new SKBitmap(new SKImageInfo((int)sizeX, (int)sizeY)))
using (var canvas = new SKCanvas(bitmap))
using (var paint = new SKPaint())
{
    canvas.Clear(SKColors.Transparent);
    var scaleX = (float)sizeX / picture.CullRect.Width;
    var scaleY = (float)sizeY / picture.CullRect.Height;
    var matrix = SKMatrix.MakeScale(scaleX, scaleY);
    canvas.DrawPicture(picture, ref matrix, paint);
    canvas.Flush();

    token.ThrowIfCancellationRequested();

    return await Decode(picture, bitmap, resolvedData).ConfigureAwait(false);
}

binding导致像素化,因为视图的初始宽度和高度用作VectorWidthand VectorHeight,这是-1default为绑定属性设置的东西。因此,您的 svg 图像分辨率一开始设置得太低,然后绑定过程会在不重绘 svg 图像的情况下放大视图。

于 2021-04-05T06:52:36.180 回答