2

我在图像文件(存储文件)和直接在 UIElement - 图像(这是一个 XAML 图像)上应用 Win2D 高斯模糊,我看到对于 BlurAmount 的相同值,我得到不同的存储文件输出输出和XAML 图像..

原始图像

在此处输入图像描述

100% 模糊应用于 XAML 图像(或任何 UIElement)时的输出

在此处输入图像描述

将 100% 模糊应用于存储文件时的输出

在此处输入图像描述


相关代码:

对于图像文件

using (var stream = await originalFile.OpenAsync(FileAccessMode.Read))
 {
    var device = new CanvasDevice();
    var bitmap = await CanvasBitmap.LoadAsync(device, stream);
    var renderer = new CanvasRenderTarget(device, bitmap.SizeInPixels.Width, bitmap.SizeInPixels.Height, bitmap.Dpi);

    using (var ds = renderer.CreateDrawingSession())
    {
      var blur = new GaussianBlurEffect();
      blur.BlurAmount = eo.effectAmount1;
      blur.BorderMode = EffectBorderMode.Hard;                       
      blur.Source = bitmap;
      ds.DrawImage(blur);                    
    }
    var saveFile = await ApplicationData.Current.TemporaryFolder.CreateFileAsync("ImageName.jpg", CreationCollisionOption.GenerateUniqueName);

    using (var outStream = await saveFile.OpenAsync(FileAccessMode.ReadWrite))
    {
       await renderer.SaveAsync(outStream, CanvasBitmapFileFormat.Png,1.0f);
    }
 }                    

对于UIElement(XAML 图像)

using (var stream = await sourceElement.RenderToRandomAccessStream())               
 {
   var device = new CanvasDevice();
   var bitmap = await CanvasBitmap.LoadAsync(device, stream);

   var renderer = new CanvasRenderTarget(device,bitmap.SizeInPixels.Width,
                                                          bitmap.SizeInPixels.Height,
                                                          bitmap.Dpi);

     using (var ds = renderer.CreateDrawingSession())
     {
       var blur = new GaussianBlurEffect();
       blur.BlurAmount = blurAmount;
       blur.Source = bitmap;
       blur.BorderMode = EffectBorderMode.Hard;
       ds.DrawImage(blur);
      }

      stream.Seek(0);
      await renderer.SaveAsync(stream, CanvasBitmapFileFormat.Png);

   }

问题:这是预期的行为吗?如果是,我怎样才能使两种情况具有相同的输出?如果没有,我做错了什么?

4

1 回答 1

2

您可以尝试使用bitmap.Size代替bitmap.SizeInPixels吗?

var renderer = new CanvasRenderTarget(bitmap, bitmap.Size);

我猜你正在经历模糊效果和像素化。

编辑 1

如果这不起作用,请在创建渲染器后提出此断言。SizeInPixels 需要匹配:

Debug.Assert(
    bitmap.SizeInPixels.Width == renderer.SizeInPixels.Width 
    && bitmap.SizeInPixels.Height == renderer.SizeInPixels.Height
);

编辑 2

如果像素没问题,请尝试将StretchMode图像元素上的 设置为None.

<Image Stretch="None" />

我只是怀疑视觉树中某处的像素化。

解释

您需要适应 DPI 比例。您的屏幕可能设置为 200%。所以,如果你有一个Image尺寸为 100x100 的控件,你实际上需要 200x200 像素的图像来填充它。如果你给它一个 100x100 的位图源,它会拉伸它以适应它。这就是你得到像素化的原因。

因此,要解决您的问题,要么禁用图像上的任何拉伸,要么根据 DPI 比例减小的源大小调整其大小。也就是说,对于 200% DPI 比例的 100x100 像素图像,将图像宽度和高度设置为 50x50。

DPI 比例可以在 UI 线程上使用:

var dpiScale = DisplayInformation.GetForCurrentView().LogicalDpi / 96f;
于 2017-10-07T05:23:50.837 回答