简体   繁体   English

WPF中3D表面问题的图像缩放质量

[英]Image scaling quality on 3D surface problem in WPF

I have an image viewer created with WPF 3D graphics. 我有一个使用WPF 3D图形创建的图像查看器。 Image quality is really WORSE there, so I've started researching this issue, created simple application which shows the image using 2D graphics on the top part of the window, and the same image on the bottom part using 3D graphics. 图像质量确实令人担忧,因此我开始研究此问题,创建了一个简单的应用程序,该应用程序使用窗口顶部的2D图形显示图像,而使用3D图形的底部显示相同图像。 I noticed that image looks much worse on 3D surface than on 2D. 我注意到在3D表面上的图像看起来比在2D表面上的图像差很多。 The colors on the 3D surface are less saturated and do not have clear boundaries. 3D表面上的颜色饱和度较低,并且没有清晰的边界。 Note, that I applied linear bitmap scaling mode to the root Grid. 注意,我将线性位图缩放模式应用于根Grid。 Other weird thing is that when I'm changing bitmap scaling mode to 'Fant' or 'NearestNeighbor' it affects 2D graphics, but image on the 3D surface REMAINS THE SAME! 另一个怪异的事情是,当我将位图缩放模式更改为“ Fant”或“ NearestNeighbor”时,它会影响2D图形,但是3D表面上的图像却是如此! I'm using image for this sample with Height = 466px, Width = 490px. 我正在为这个样本使用图像,高度= 466px,宽度= 490px。 I'm zooming out it in the code (both 2D and 3D implementation) a little bit to see the scaling quality degradation. 我在代码中将其缩小(包括2D和3D实现),以查看缩放质量下降。 The code is: 代码是:

<Window x:Class="Scaling3DSample.Window2"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Width="340">
        <Grid x:Name="backgroundGrid">
            <Grid.RowDefinitions>
                <RowDefinition />
                <RowDefinition />
            </Grid.RowDefinitions>
        </Grid>
</Window>

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Media.Media3D;
using System.Windows.Shapes;
    namespace Scaling3DSample
    {
        public partial class Window2 : Window
        {
            private static double _distanceFromCamera = 0.62618;

            public Window2()
            {
                InitializeComponent();
                RenderOptions.SetBitmapScalingMode(backgroundGrid, BitmapScalingMode.Linear);
                Create2DGraphics();
                // THE SAME IMAGE ON 3D SURFACE LOOKS MUCH WORSE
                Create3DGraphics();
            }

            private void Create2DGraphics()
            {
                Rectangle exampleRectangle = new Rectangle();
                Grid.SetRow(exampleRectangle, 0);

                exampleRectangle.Width = 335;
                exampleRectangle.Height = 317;
                exampleRectangle.Fill = GetBrush();
                backgroundGrid.Children.Add(exampleRectangle);
            }

            private void Create3DGraphics()
            {
                Viewport3D mainViewPort3D = new Viewport3D();
                Grid.SetRow(mainViewPort3D, 1);

                mainViewPort3D.Camera = new PerspectiveCamera { LookDirection = new Vector3D(-1, 0, 0), UpDirection = new Vector3D(0, 0, 1), FieldOfView = 77.0942 };
                mainViewPort3D.Children.Add(new ModelVisual3D { Content = new AmbientLight() });

                MeshGeometry3D geometry3D = new MeshGeometry3D();

                Point3D topLeft = new Point3D(-_distanceFromCamera, 0.5, -0.5);
                Point3D bottomRight = new Point3D(-_distanceFromCamera, -0.5, 0.5);

                geometry3D.Positions.Add(bottomRight);
                geometry3D.Positions.Add(new Point3D(-_distanceFromCamera, topLeft.Y, bottomRight.Z));
                geometry3D.Positions.Add(new Point3D(-_distanceFromCamera, bottomRight.Y, topLeft.Z));
                geometry3D.Positions.Add(topLeft);

                geometry3D.TriangleIndices.Add(1);
                geometry3D.TriangleIndices.Add(0);
                geometry3D.TriangleIndices.Add(2);

                geometry3D.TriangleIndices.Add(2);
                geometry3D.TriangleIndices.Add(3);
                geometry3D.TriangleIndices.Add(1);

                geometry3D.TextureCoordinates.Add(new Point(0, 0));
                geometry3D.TextureCoordinates.Add(new Point(1, 0));
                geometry3D.TextureCoordinates.Add(new Point(0, 1));
                geometry3D.TextureCoordinates.Add(new Point(1, 1));

                Material material = new DiffuseMaterial(GetBrush());

                ModelVisual3D modelForGeometry = new ModelVisual3D { Content = new GeometryModel3D(geometry3D, material) };
                mainViewPort3D.Children.Add(modelForGeometry);
                backgroundGrid.Children.Add(mainViewPort3D);
            }

            private ImageBrush GetBrush()
            {
            // put any other image URI here, image Height = 466px, Width = 490px
                ImageBrush brush = new ImageBrush(new BitmapImage(new Uri("lion.jpg", UriKind.Relative)));
                brush.Stretch = Stretch.Fill;
                return brush;
            }
        }
    }

Thanks in advance for all your help! 预先感谢您的所有帮助!

Just guessing: you did not define any lights nor any normals. 只是猜测:您没有定义任何灯光或任何法线。 Sometimes that will cause a darker image than you would expect. 有时,这会导致图像变暗,超出您的预期。

There are some other variables to consider, then. 然后,还需要考虑其他一些变量。

Your graphics card settings could be forcing the interpolation mode down despite WPF's request for something nicer looking. 尽管WPF要求提供更好的外观,但您的图形卡设置可能会强制降低插值模式。 WPF's 3D is hardware accelerated on Tier 2 hardware, so check your drivers' control software. WPF的3D在第2层硬件上通过硬件加速,因此请检查驱动程序的控制软件。 It might not be possible for WPF to request anything better! WPF可能无法请求更好的任何东西!

Try enabling anti-aliasing in your application and graphics card settings, too. 也尝试在应用程序和图形卡设置中启用抗锯齿。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM