C# 如何在Xamarin Forms UWP中获得更好的图像缩放?
当UI在UWP中将我的应用程序中的图像元素缩小到一个小尺寸时,缩放的质量看起来很差,就像是通过旧的“最近邻”样式进行缩放,这使得它非常像素化: 当我在Android上运行相同的应用程序时,它看起来很好: 这些图像通过使用TMDB API的URL显示。有没有办法控制它使用的图像缩放算法 如何在Xamarin Forms UWP中获得更好的图像缩放 请参考UWP图像文件和性能,如果您正在参考一个图像文件,其中您知道源文件是一个大的高分辨率图像,但您的应用程序在一个小于图像自然大小的UI区域中显示它,则应设置C# 如何在Xamarin Forms UWP中获得更好的图像缩放?,c#,xamarin.forms,uwp,C#,Xamarin.forms,Uwp,当UI在UWP中将我的应用程序中的图像元素缩小到一个小尺寸时,缩放的质量看起来很差,就像是通过旧的“最近邻”样式进行缩放,这使得它非常像素化: 当我在Android上运行相同的应用程序时,它看起来很好: 这些图像通过使用TMDB API的URL显示。有没有办法控制它使用的图像缩放算法 如何在Xamarin Forms UWP中获得更好的图像缩放 请参考UWP图像文件和性能,如果您正在参考一个图像文件,其中您知道源文件是一个大的高分辨率图像,但您的应用程序在一个小于图像自然大小的UI区域中显示
DecodePixelWidth
属性或DecodePixelHeight
。对于xamarin表单项目,我们建议您使用重新渲染图像
[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"
/>
分辨率取决于硬件上每英寸的像素数。您没有说明第一个应用程序使用的机器。只有第二个应用程序是Android,所以我必须假设第一个不是Android。我必须假设第一个屏幕上每英寸的像素数与第二个屏幕上的像素数不同。我说的是UWP,UWP是Windows10。当分辨率相同时,Android版本看起来更平滑。它似乎使用了比UWP版本更好的缩放插值。问题是,UWP版本在windows中运行,这意味着人们可以动态地使窗口变大或变小,我不想每次都要重新渲染或解码图像。对于良好的过滤,比如最小双线性插值,这应该是不必要的。WPF的图像控件中有renderopions.BitmapScalingMode=“HighQuality”,但我很难在Xamarin甚至独立的UWP.yep中找到类似的内容。是的,目前,没有像WPF BitmapScalingMode这样的选项,因此,我们建议您根据图像控件大小(如案例更新)设置DecodePixelHeight DecodePixelWidthpart@morphinapg我已经根据图像大小的变化用dynamic DecodePixelSize更新了案例回复,是否有效?我正在尝试让它正常工作,但我需要在代码中设置图像的Uri,而不是XAML,因为它是从API或我的数据库加载的,而且我只需要在UWP上使用它,因为Android工作正常。现在我正在做ShowImage.SetBinding(ImageEffect.TextProperty,uri.AbsoluteUri);但这似乎没有什么作用。我已经将ImageEffect复制到主项目中,并将ImageSourceEffect复制到UWP项目中。我想那是对的?还有什么我需要做的吗?如果在代码中设置uri,更好的解决方案是为图像控制制作自定义渲染,并在本机渲染中处理位图,您可以参考这一点。
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()
{
}
}