WPF:在通过LayoutTransform修改大小的图像中获得1:1像素渲染

问题描述 投票:0回答:1

首先要说的是,我已经对此进行了广泛的搜索,找到了部分答案,但没有任何办法一直有效。

我需要在WPF应用程序中显示未缩放的位图图像。我想将位图的1像素映射到显示器的1像素。我确实打算通过提供多个版本的位图来支持多种分辨率。但是我想知道,当选择了一个特定的位图时,它会按照设计的样子完全渲染。

我克服WPF中发生的自动缩放的策略是查看正在自动应用的内容(通过OS DPI设置),然后将与之相反的LayoutTransform应用于我的窗口的最外层容器。

这可确保,无论用户的DPI设置是什么,应用程序都会以1:1的WPF像素与硬件像素的比例呈现窗口内容。到目前为止,一切都很好。

该代码如下所示。 (假设使用1.0的参数调用它。)>

    private void SetScale(double factor)
    {
        // First note the current window transform factor.
        // This is the factor being applied to the entire window due to OS DPI settings.
        Matrix m = PresentationSource.FromVisual(this).CompositionTarget.TransformToDevice;
        double currentWindowTransformFactorX = m.M11;
        double currentWindowTransformFactorY = m.M22;

        // Now calculate the inverse.
        double currentWindowTransformInverseX = (1 / m.M11);
        double currentWindowTransformInverseY = (1 / m.M22);

        // This factor will put us "back to 1.0" in terms of a device-independent-pixel to physical pixel mapping.
        // On top of this, we can apply our caller-specified factor.
        double transformFactorX = currentWindowTransformInverseX * factor;
        double transformFactorY = currentWindowTransformInverseY * factor;

        // Apply the transform to the registered target container
        ScaleTransform dpiTransform = new ScaleTransform(transformFactorX, transformFactorY);
        if (dpiTransform.CanFreeze)
            dpiTransform.Freeze();

        this.pnlOutermost.LayoutTransform = dpiTransform;
    }

到目前为止,一切正常。无论我将Windows DPI设置为什么,该主容器的内容始终完全相同,并且位图精确呈现。

现在是有趣的部分。我想通过提供特定于分辨率的图稿并适当缩放整个UI来支持不同的屏幕分辨率。

事实证明LayoutTransform对此非常有效。因此,如果我用1.25或1.5或更高的值调用上述方法,则整个UI都会缩放,并且一切看起来都很完美...除了我的图像,即使我将源更改为完全适合新的缩放尺寸。

例如,假设我在XAML中有一个100x100的图像。我的作品具有三种风格:100x100、125x125和150x150。当我缩放容纳图像的容器时,我还将图像的来源更改为适当的来源。

有趣的是,如果图像对象位于一个位置,当按比例缩放时会产生积分结果,则缩放后的图像看起来很好。也就是说,假设图像具有以下属性:

Canvas.Left = 12
Canvas.Top = 100

当我们应用1.25的因子时,得出15和125,图像看起来很棒。但是,如果图像移动了一个像素,请说:

Canvas.Left = 13
Canvas.Top = 100

现在,当我们应用1.25的因子时,我们得到15.25和125,结果看起来很糟糕。

显然,这看起来像是四舍五入的问题或类似的东西。所以我尝试了:

UseLayoutRounding="True"
SnapsToDevicePixels="True"
RenderOptions.EdgeMode="Aliased" 
RenderOptions.BitmapScalingMode="NearestNeighbor"

我已经在窗口中,正在缩放的​​容器中以及在图像对象中尝试过这些。没有任何效果。而且,BitmapScalingMode还是没有任何意义,因为根本不应该缩放图像。

永远感谢任何可以阐明这一点的人。

让我开始说,我已经对此进行了广泛的搜索,找到了部分答案,但是没有任何方法一直有效。我需要在WPF应用程序中显示不是...

wpf image xaml bitmap layouttransform
1个回答
0
投票

我遇到了完全相同的问题,因此看来截至2019年该问题尚未在框架中得到解决。

© www.soinside.com 2019 - 2024. All rights reserved.