问题描述
当我的应用中的图像元素被 UI 缩小到 UWP 中的小尺寸时,缩放看起来质量很差,就像它是通过旧的“最近邻”样式缩放的一样,这使得它非常像素化:>
当我在 Android 上运行相同的应用程序时,它看起来不错:
这些图像是使用 TMDB API 从 URL 显示的。有什么方法可以控制它使用的图像缩放算法吗?
解决方法
如何在 Xamarin Forms UWP 中获得更好的图像缩放?
请参考 UWP 图像文件和性能 document,如果您引用的图像文件知道源文件是大的高分辨率图像,但您的应用在较小的 UI 区域中显示它比图像的自然大小,您应该设置 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()
{
}
}