5

我在 Windows 运行时环境中将图像实例添加到画布,当在 140 和 180 比例分辨率显示时,我的图像不断放大,它在比例分辨率 100 时看起来很完美。我尝试创建 3 个 PNG 图像,每个比例大小一个:100 , 140, 180 但它仍然放大它们并且看起来模糊。我在青色背景上创建了一个带有 4 个黑色像素的测试图像,并从模拟器中截取了屏幕截图,看看图像是如何模糊的,我的原始图像只有 4 个完美的黑色像素:

它很模糊,相信我

我尝试更改图像对象的拉伸模式,但它什么也没做。我正在使用此代码在运行时添加图像:

var bitmapImage = new BitmapImage();
StorageFile bitmapFile = await StorageFile.GetFileFromApplicationUriAsync(imageUri);
await bitmapImage.SetSourceAsync(await bitmapFile.OpenReadAsync());

Image image = new Image{ Source = bitmapImage};
image.SetValue(Canvas.LeftProperty, x);
image.SetValue(Canvas.TopProperty, y);
canvas.Children.Add(image);

如何让图像在画布中完美地绘制像素而不缩放并且在我想要的确切 x/y 坐标处?

4

5 回答 5

2

我想我有一个解决方法,但它需要两个步骤:

首先,我必须使用一种更标准的方式来加载图像,这种方式不涉及像这样获取文件路径。

var bitmapImage = new BitmapImage(imageUri);

不知何故,这必须在内部保留更多信息,即该图像来自具有当前显示的相应 ResolutionScale 的文件。因此,当它被画布绘制时,它根本没有缩放。然而,这只解决了一半的问题。

下一个问题是用于指定图像绘制位置的 x、y 坐标正在缩放,因此图像绘制在错误的位置,比我想要的位置更远。我唯一能做的就是先取消缩放它们,如下所示:

var resScale = DisplayInformation.GetForCurrentView().ResolutionScale;
Image image = new Image{ Source = bitmapImage};
image.SetValue(Canvas.LeftProperty, (x * 100.0) / (int)resScale);
image.SetValue(Canvas.TopProperty, (y * 100.0) / (int)resScale);
canvas.Children.Add(image);

整个事情似乎有点疯狂,但到目前为止似乎还有效......任何人都有更好的解决方案或解释为什么这一切都是必要的?似乎 Canvas 类需要一个未缩放的模式,它不会与不同分辨率显示器上的图像或坐标混淆。

更新:这并不完美,使用双精度存储值会导致精度损失,有时还会出现抗锯齿伪影。如果您想要像素完美的图形,这是不可接受的。我仍在寻找完美的解决方案。

于 2013-09-21T06:39:15.427 回答
2

还有一些事情可能对您的解决方案有所帮助。

  1. UseLayoutRounding="False"在您的图像上使用。
  2. 将您的屏幕设置为Canvas全屏Viewbox,然后将Canvas Width和设置Height为屏幕分辨率。在这种情况下,您将使用未缩放的Canvas.Left/Top值。
  3. 使用 Direct2D/Direct3D 进行渲染。

祝你好运。

于 2013-09-24T02:24:12.063 回答
1

You can change the Stretch property to "None", If you image is still meshed-up:

You should look at what DPI it is saved on. WPF tries to be DPI-independend, so it tries to draw an image of 5"x5" on every monitor the same size. Even when the resolution is higher, it still should be 5"x5" only a high resolution would render(rasterize) the image in higher quality.

Here's some info: http://www.wpflearningexperience.com/?p=41

How do I convert a WPF size to physical pixels?

于 2013-09-20T22:28:08.303 回答
0

这是一段xaml代码

您始终可以使用后面代码的缩放变换将图像缩放到适当的数量,无论是少还是多。

<Image  Canvas.Left="150"  Height="170" Width="170" Visibility="Visible" Stretch="None">
                <Image.Source >
                    <BitmapImage UriSource="ms-appx:///Assets/rollingDieSprite.png"></BitmapImage>
                </Image.Source>

                <Image.RenderTransform>
                    <ScaleTransform ScaleX="4" ScaleY="4" x:Name="scaleTfDie"></ScaleTransform>
                </Image.RenderTransform>
            </Image>

在后面的 c# 代码中,您可以执行以下操作

ScaleTransform sc = new ScaleTransform();
            sc.ScaleX = 0.9;
            sc.ScaleY = 0.9;
            imgDieRolling.RenderTransform = sc;

这将控制缩放。尝试使用 fill=none 。让我知道它是否有效。

于 2013-09-24T06:24:44.867 回答
0

我发现这个问题也很成问题。我正在创建自定义位图并将它们绘制在画布上的不同位置。我在 XAML 中找不到方法,但我找到了使用 Direct2D 的方法。设置 D2DContext 时,有一个名为 SetUnitMode() 的函数。默认单位模式是“DIPS”,这会导致所有图形都被缩放。通过切换到 PIXELS 模式,系统会停止缩放绘图并以 1:1 的比例进行所有操作。

m_d2dContext->SetUnitMode(D2D1_UNIT_MODE_PIXELS);
于 2013-10-27T19:21:36.390 回答