如何在 Xamarin Forms UWP 中获得更好的图像缩放?
请参考 UWP 图像文件和性能document,如果您在引用图像文件时知道源文件是大的高分辨率图像,但您的应用在小于图片的自然尺寸,你应该设置DecodePixelWidth属性,或者DecodePixelHeight。对于 xamarin 表单项目,我们建议您使用effect 重新渲染图像。
[assembly: ResolutionGroupName("MyCompany")]
[assembly: ExportEffect(typeof(ImageFormsTest.UWP.ImageSourceEffect), nameof(ImageEffect))]
public class ImageSourceEffect : PlatformEffect
{
protected override void OnAttached()
{
try
{
var control = Control ?? Container;
if (control is DependencyObject)
{
var image = control as Windows.UI.Xaml.Controls.Image;
var uri = ImageEffect.GetText(Element);
var bitmap = new BitmapImage(new Uri(uri)) { DecodePixelHeight = 300, DecodePixelWidth = 600 };
image.Source = bitmap;
}
}
catch (Exception ex)
{
Debug.WriteLine("Cannot set property on attached control. Error: ", ex.Message);
}
}
protected override void OnDetached()
{
}
}
表单代码部分
public static class ImageEffect
{
public static readonly BindableProperty TextProperty =
BindableProperty.CreateAttached("Text", typeof(string), typeof(ImageEffect), string.Empty, propertyChanged: OnTextChanged);
public static string GetText(BindableObject view)
{
return (string)view.GetValue(TextProperty);
}
public static void SetText(BindableObject view, string value)
{
view.SetValue(TextProperty, value);
}
static void OnTextChanged(BindableObject bindable, object oldValue, object newValue)
{
var view = bindable as View;
if (view == null)
{
return;
}
string text = (string)newValue;
if (!string.IsNullOrEmpty(text))
{
view.Effects.Add(new SourceEffect());
}
else
{
var toRemove = view.Effects.FirstOrDefault(e => e is SourceEffect);
if (toRemove != null)
{
view.Effects.Remove(toRemove);
}
}
}
}
public class SourceEffect : RoutingEffect
{
public SourceEffect() : base($"MyCompany.{nameof(ImageEffect)}")
{
}
}
用法
<Image
x:Name="TitleImage" effect:ImageEffect.Text="https://xxxx.jpg"
/>
更新
public class ImageSourceEffect : PlatformEffect
{
protected override void OnAttached()
{
try
{
var control = Control ?? Container;
if (control is DependencyObject)
{
var image = control as Windows.UI.Xaml.Controls.Image;
var uri = ImageEffect.GetText(Element);
var bitmap = new BitmapImage(new Uri(uri));
bitmap.ImageOpened += Bitmap_ImageOpened;
image.Source = bitmap;
image.SizeChanged += Image_SizeChanged;
}
}
catch (Exception ex)
{
Debug.WriteLine("Cannot set property on attached control. Error: ", ex.Message);
}
}
private void Image_SizeChanged(object sender, SizeChangedEventArgs e)
{
if (bitmapImage != null)
{
bitmapImage.DecodePixelType = DecodePixelType.Logical;
bitmapImage.DecodePixelHeight = (int)e.NewSize.Height;
bitmapImage.DecodePixelWidth = (int)e.NewSize.Width;
}
}
private BitmapImage bitmapImage;
private void Bitmap_ImageOpened(object sender, RoutedEventArgs e)
{
bitmapImage = sender as BitmapImage;
}
protected override void OnDetached()
{
}
}