【问题标题】:Scaling image using Bitmaptransform gives blured images in win2d使用 Bitmaptransform 缩放图像会在 win2d 中提供模糊图像
【发布时间】:2020-05-23 16:08:16
【问题描述】:

这是我尝试过的:

var decoder = await BitmapDecoder.CreateAsync(fileStream);
BitmapTransform bitmapTransform = new BitmapTransform();
bitmapTransform.ScaledHeight = 300;
bitmapTransform.ScaledWidth = 800;

var pixelProvider = await decoder.GetPixelDataAsync(
                    BitmapPixelFormat.Bgra8,
                    BitmapAlphaMode.Ignore,
                    bitmapTransform,
                    ExifOrientationMode.IgnoreExifOrientation,
                    ColorManagementMode.DoNotColorManage);

byte[] by = pixelProvider.DetachPixelData();
CanvasBitmap cb = CanvasBitmap.CreateFromBytes(sender,by,800,300,Windows.Graphics.DirectX.DirectXPixelFormat.B8G8R8X8UIntNormalized);

我在CanvasControl的Draw事件中做了什么:

private  void Canvas_Draw(CanvasControl sender, CanvasDrawEventArgs args)
{
args.DrawingSession.DrawImage(cb);
}

由于缩放,图像变得模糊。我该如何解决这个问题?我需要在运行时动态更改图像的宽度和高度,我该怎么做? 我的原图:

绘制后(模糊图像):

【问题讨论】:

    标签: c# uwp win2d


    【解决方案1】:

    出现这种情况,说明你的图片分辨率超过了你给定的控件尺寸。而像素走样是由插值算法引起的。

    默认情况下,图片缩放时使用的插值算法为Linear,如果想在较小的控件上渲染分辨率较大的图片,可以使用Fant算法。

    bitmapTransform.ScaledHeight = 300;
    bitmapTransform.ScaledWidth = 800;
    bitmapTransform.InterpolationMode = BitmapInterpolationMode.Fant;
    

    如果打算动态改变图片的宽高,建议使用ViewBox作为CanvasControl容器。

    <Viewbox Stretch="Uniform" StretchDirection="Both" x:Name="MyViewbox">
        <xaml:CanvasControl />
    </Viewbox>
    

    然后你可以在运行时改变 Viewbox 的大小。

    MyViewbox.Width = 400;
    MyViewbox.Height = 150;
    

    谢谢。

    【讨论】:

    • @ Richard Zhang -MSFT,Viewbox 不适用于我的情况,因为我需要在不同位置的一个 canvasControl 中绘制多个图像。但是 InterpolationMode.Fant 帮助了我。现在绘制的图像看起来更好比以前。但是还是有点模糊。还有其他准确的方法吗??
    • 另一种简单的方法是用BitmapImage的Image控件,例如:MyImage.Source = new BitmapImage (new Uri ("image_url")) {DecodePixelWidth = 800}但是图片的缩放是重新排列像素的过程。你可以想象把 1000x1000 个不同颜色的小球放在一个 100x100 的盒子里,最后会丢失很多信息。不同的算法将以不同的方式重新排列像素。目前InterpolationMode有四种算法,但无论哪一种,都会有像素取舍,最终效果总会有瑕疵。
    • 不管是CanvasControl还是Image,根据控件大小缩放和重新排列的原则是一致的,你可以试试其他BitmapInterpolationMode看看哪一个更适合你的需求。
    【解决方案2】:

    您可以使用 Win2d 效果快速完成工作。

     var ScaledImage = new Microsoft.Graphics.Canvas.Effects.ScaleEffect(
    Source = source, new Vector2(2f, 2f);)
    

    上面的函数产生一个ScaleEffect,它实现了ICanvasBitmap,所以你可以直接用DrawingSession.DrawImage渲染它

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-01-19
      • 2014-10-21
      • 2014-06-07
      • 1970-01-01
      • 2012-09-19
      • 1970-01-01
      相关资源
      最近更新 更多