【问题标题】:FFImageLoading, SVGCachedImage blurry when setting HeightRequest/WidthRequest from a bindingFFImageLoading, SVGCachedImage 从绑定设置 HeightRequest/WidthRequest 时模糊
【发布时间】:2021-04-05 15:00:25
【问题描述】:

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

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

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

【问题讨论】:

  • 您是否尝试过将 DownSampleToViewSize 设置为 true?如果没有,你能告诉我行为吗?
  • 它使图像变小但仍然模糊。我还尝试监听视图模型上属性的更改,然后调用 ReloadImage()。这没有做任何事情。看起来有一种方法可以使其无效并重新绘制。
  • 告诉我 SVG 图像的宽度和高度以及您绑定到的值,如果这些值没有相同的纵横比,可能会使图像像素化,您需要保留相同的尺度
  • 啊...是的,我将高度和宽度都绑定到相同的基础值,因此图标是方形的。还要记住,我已经通过对值进行硬编码进行了测试。例如,宽度和高度分别为 80 和 80 或 100 和 100。硬编码后,图像看起来正确。当我绑定到 VM 时,图标是 very 像素化的。这些硬编码值在 ViewModel 生成的值范围内。
  • 你是通过url还是本地文件加载SVG图像?可以尝试通过本地文件加载 SVG 图像,如果可以得到相同的结果。

标签: xamarin xamarin.forms xamarin.android xamarin.ios ffimageloading


【解决方案1】:

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

<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 图像的大小,同时不会导致它变得模糊。

【讨论】:

    【解决方案2】:

    为了解决缩放视图时的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);
        }
    }
    

    根据FFImageLoadingsource code,SVG图像大小由SvgImageSource.VectorWidthSvgImageSource.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 导致像素化,因为视图的初始宽度和高度用作VectorWidthVectorHeight,即-1 或您为绑定属性设置为default 的东西。因此,您的 svg 图像分辨率一开始设置得太低,然后绑定过程会在不重绘 svg 图像的情况下放大视图。

    【讨论】:

      猜你喜欢
      • 2017-07-07
      • 2019-10-14
      • 1970-01-01
      • 2019-03-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-22
      相关资源
      最近更新 更多