如何让 ScrollViewer 放大以查看单个像素?

How to get a ScrollViewer to zoom in to see individual pixels?

我正在为 Windows 8.1 制作一个应用程序,其中重要的是能够放大和详细检查图像。如果我只是打开位图并放大它看起来像。

然而,当我将图像加载到我的应用程序并使用 ScrollViewer 放大时,我得到了。

因为它似乎在尝试为某种抗锯齿插入像素值。

我怎样才能得到它以便在我放大时它能(尽可能地)显示图像的精确像素?特别是我将图像用作滚动查看器中包含的 canvas 的背景。


我在这里和 MSDN 上四处查看,发现了一对相关问题,但到目前为止,它们似乎还没有解决我的确切问题。

没有简单的方法来解决这个问题,最好的选择是使用 DirectX 渲染更大的图像,这样您就可以减轻 WinRT 自动插值像素值的影响。

作为 someone explained on MSDN and based on this outstanding request 我看不出有任何其他方法可以做到这一点。

使用 Win2D

Win2D 是 WinRT 的 DirectX 互操作库。有了它,您可以以更大的尺寸渲染图像,然后将 scrollViewier 的默认缩放级别设置为非常小。因此,当您放大时,您似乎可以看到没有任何 fuzzy/blurry 插值的单个像素,因为您实际上会看到 64 像素的组,或者所有像素都是一种颜色。我找不到任何方法来实际覆盖完成的插值类型,所以这似乎是最好的方法。

  1. 使用 Visual Studio 将 Win2D 作为 NuGet 包下载,Win2D 的 快速入门指南很好地解释了一些设置
  2. 设置您的 canvas 和绘图事件并使用 DrawImage 函数渲染更大的图像

    <ScrollViewer x:Name="Scroller" ZoomMode="Enabled"
          MinZoomFactor="0.1" MaxZoomFactor="20">
        <canvas:CanvasControl x:Name="canvas" Draw="canvas_Draw" CreateResources="create"/>
    </ScrollViewer>
    

在canvas_draw函数中。

canvas.Width = original.Width * 10;
canvas.Height = original.Height * 10;
args.DrawingSession.DrawImage(bitmap,new Rect(0,0,original.Width*10,original.Height*10), new Rect(0,0,original.Width,original.Height), 1.0f, CanvasImageInterpolation.NearestNeighbor);
  1. 确保也将 canvas 设置得更大
  2. 在您后面的代码中,将 ScrollVieiwer 的默认缩放设置为合适的,这样您的图像看起来大小相同。

在页面构造函数中

Scroller.ZoomToFactor (0.1f);

我研究过但没有奏效的其他方法

  • 使 canvas 非常大并使用 BitmapEncoder/BitmapDecoder 并将插值模式设置为 NearestNeighbor,即使缩放到 2 的幂大小也会引入很多视觉伪像
  • 渲染选项似乎只在 WPF 中可用,在 WinRT 中不可用

也可以使用一些图像处理库将位图简单地放大 10 倍左右然后使用它,但我最终改用了 Win2D。