XAML Image Quality (interpolation) in a Metro-Styl

2019-02-17 17:12发布

问题:

Given the following Image object (it's in the DataTemplate of a ListView object):

  <Image Source="{Binding ImgSource}" ImageOpened="img_ImageOpened" />

how am I supposed to get an high-quality bicubic-interpolated image? (on screen, the size of this Image is smaller than the source PNG, but the default resizing appears to be performed with the poor-quality "nearest neighbor" interpolation).

Since I would like to rely on data binding alone (whenever the ImgSource of the associated data item changes, the Image content should change), I've tried to set an ImageOpened handler and change the just-loaded image to a better-quality one.

Unfortunately, the code below seems not to work (I just get empty images):

    async void LoadImage(Image imgControl, string source)
    {
        try
        {
            StorageFile file = await StorageFile.GetFileFromPathAsync(source);

            IRandomAccessStream fileStream = await file.OpenAsync(FileAccessMode.Read);
            BitmapDecoder decoder = await BitmapDecoder.CreateAsync(fileStream);

            InMemoryRandomAccessStream ras = new InMemoryRandomAccessStream();
            BitmapEncoder enc = await BitmapEncoder.CreateForTranscodingAsync(ras, decoder);

            enc.BitmapTransform.InterpolationMode = BitmapInterpolationMode.Cubic;
            enc.BitmapTransform.ScaledHeight = Convert.ToUInt32(imgControl.ActualHeight);
            enc.BitmapTransform.ScaledWidth = Convert.ToUInt32(imgControl.ActualWidth);

            await enc.FlushAsync();

            Windows.UI.Xaml.Media.Imaging.BitmapImage bImg = new Windows.UI.Xaml.Media.Imaging.BitmapImage();
            bImg.SetSource(ras);
            imgControl.Source = bImg;
        }
        catch (Exception e)
        {
            return;
        }
    }

    void img_ImageOpened(object sender, RoutedEventArgs e)
    {
        Image imgControl = (Image)sender;
        LoadImage(imgControl, <path to PNG file>);
    }

回答1:

I faced the same image quality problem in my WinRT application, and tried to use RenderOptions.BitmapScalingMode but it is not present (and System.Windows.Media namespace as well) in .NET for Windows Store. So I tried your first solution and fixed it so that works. You were one small step from success, only need to add

ras.Seek(0);

to allow reading the stream from the beginning.



回答2:

I know it is a little bit late, but it may be a useful reference for someone else. There's no need for such handler: you only need to set the value of the RenderOptions.BitmapScalingMode attached property.

<Image Source="{Binding ImgSource}" ImageOpened="img_ImageOpened" RenderOptions.BitmapScalingMode="HighQuality" />