我正在使用FFImageLoading在我的Xamarin.Forms项目中显示svg图标。我的理解是,必须显式设置Height和Width请求,才能正确呈现SVG。每当我试图将Height/Width请求绑定到ViewModel上的值时,我都会得到很多像素化(我需要这样做,因为所需的大小取决于数据(。如果我明确设置大小,一切看起来都很好。
每当Height/Width请求的绑定发生更改时,SvgCachedImage是否不重新绘制SVG?
如果没有,当大小发生变化时,我有没有办法明确强制它们无效并重新绘制?
通过将"水平"one_answers"垂直"选项设置为填充而不是"中心:"来解决模糊问题
<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图像的大小,同时不会使其变得模糊。
为了解决缩放视图大小时的svg模糊问题,
- 更改
SvgImageSource.VectorWidth
或SvgImageSource.VectorHeight
- 重新加载图像
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
会导致像素化,因为视图的初始宽度和高度被用作VectorWidth
和VectorHeight
,即-1
或您为绑定属性设置为default
的东西。因此,您的svg图像分辨率设置太低,然后绑定过程放大视图,而不重新绘制svg图像。