【问题标题】:How to save a non-fuzzy image of a control in WPF?如何在 WPF 中保存控件的非模糊图像?
【发布时间】:2014-06-11 13:53:00
【问题描述】:

我正在使用 DrawingContext 来绘制图像。然后我将结果渲染到 RenderTargetBitmap。我还将画布渲染到相同的 RenderTargetBitmap。尽管像素边界在屏幕上很清晰,但保存时它们会变得模糊不清。

在下面的屏幕截图中,您可以看到问题(BitmapScalingMode = NearestNeighbor)。

这里是 BitmapScalingMode = HighQuality。它更光滑但不清脆和干净。

这是我的代码的相关部分。您可以看到我尝试在多个位置设置 RenderOptions 但似乎没有效果。

        DrawingVisual drawingVisual = new DrawingVisual();
        RenderTargetBitmap result = new RenderTargetBitmap((int)size.Width, (int)size.Height, 96, 96, PixelFormats.Pbgra32);

        RenderOptions.SetBitmapScalingMode(drawingVisual, BitmapScalingMode.NearestNeighbor);   // This forces the scaling to be on even-pixel boundaries
        RenderOptions.SetBitmapScalingMode(drawCanvas, BitmapScalingMode.NearestNeighbor);  // This forces the scaling to be on even-pixel boundaries
        RenderOptions.SetBitmapScalingMode(result, BitmapScalingMode.NearestNeighbor);  // This forces the scaling to be on even-pixel boundaries

        using (DrawingContext context = drawingVisual.RenderOpen()) {
            context.DrawRectangle(Brushes.Black, null, new Rect(new Point(), new Size(size.Width, size.Height)));

            if (layers.Count >= 1 && layers[0].LayerImage != null && layers[0].LayerImage.Source != null && gridImage.Children[1].Visibility == System.Windows.Visibility.Visible)
                context.DrawImage(layers[0].LayerImage.Source, new Rect(size)); // Draw first image.

            context.Close();
        }

        result.Render(drawingVisual);

        drawCanvas.Measure(drawCanvas.RenderSize);
        drawCanvas.Arrange(new Rect(drawCanvas.RenderSize));

        for (int i = 0; i < drawCanvas.Children.Count; i++) {
            RenderOptions.SetBitmapScalingMode(drawCanvas.Children[i], BitmapScalingMode.NearestNeighbor);  // This forces the scaling to be on even-pixel boundaries
        }

        result.Render(drawCanvas);

        BitmapEncoder encoder = new PngBitmapEncoder();
        if (result!= null) {
            encoder.Frames.Add(BitmapFrame.Create((BitmapSource)result));
            encoder.Save(fileStream);
        }

【问题讨论】:

  • 尝试将您的 BitmapScalingMode 更改为 HighQuality
  • 上次我还以为我有这个问题,它确实是一个 IfranView 显示选项。
  • @lll:我尝试了 HighQuality,但它并没有真正帮助。请参阅上面编辑中的屏幕截图。
  • @TAW:我在很多程序中都试过了,包括我自己的程序,它们看起来都一样,所以我认为这是我的保存代码而不是查看器。
  • @TaW 你不能混合 System.Drawing 和 WPF

标签: c# wpf render blurry rendertargetbitmap


【解决方案1】:

我不知道你是否已经解决了这个问题,但该功能对我来说效果很好。

    public BitmapSource SnapShotPNG(UIElement source)
    {
        double actualWidth = source.RenderSize.Width;
        double actualHeight = source.RenderSize.Height;

        RenderTargetBitmap renderTarget = new RenderTargetBitmap((int)actualWidth, (int)actualHeight, 96, 96, PixelFormats.Pbgra32);


        DrawingVisual visual = new DrawingVisual();

        using (DrawingContext context = visual.RenderOpen())
        {
            VisualBrush sourceBrush = new VisualBrush(source);
            context.DrawRectangle(sourceBrush, null, new Rect(new Point(0, 0), new Point(actualWidth, actualHeight)));
        }
        source.Measure(source.RenderSize); //Important
        source.Arrange(new Rect(source.RenderSize)); //Important

        renderTarget.Render(visual);

        try
        {
            return new CroppedBitmap(renderTarget, new Int32Rect(0, 0, (int)actualWidth, (int)actualHeight));
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
            return null;
        }
    }

【讨论】:

  • 谢谢!我试试看。
  • 还没有,抱歉!自从我发布帖子以来,我的代码已被重新​​格式化,因此我需要对其进行去卷积以弄清楚如何测试您的功能。敬请期待!
  • 我一直在使用类似的东西,但必须实际运行测量 + 排列,宽度和高度大 1 个像素,然后以正确的大小再次运行。如果您发现任何未渲染的东西有任何奇怪之处,请尝试 [原文如此]
【解决方案2】:
 public static BitmapSource CaptureScreen(this UIElement visualElement, int? desiredLongestEdge = null)
    {
        double scale = 1;
        if (desiredLongestEdge.HasValue)
        {
            if (visualElement.RenderSize.Width > visualElement.RenderSize.Height)
            {
                scale = desiredLongestEdge.Value/ visualElement.RenderSize.Width;
            }
            else
            {
                scale = desiredLongestEdge.Value / visualElement.RenderSize.Height ;
            }
        }

        var targetBitmap =
                     new RenderTargetBitmap(
                        (int) Math.Ceiling(scale * (visualElement.RenderSize.Width + 1)),
                         (int) Math.Ceiling(scale * (visualElement.RenderSize.Height + 1)),
                                                       scale * 96,
                                                       scale * 96,
                                                        PixelFormats.Pbgra32);

        visualElement.Measure(visualElement.RenderSize); //Important
        visualElement.Arrange(new Rect(visualElement.RenderSize)); //Important

        targetBitmap.Render(visualElement);

        return targetBitmap;
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-12-26
    • 1970-01-01
    • 1970-01-01
    • 2014-06-13
    • 1970-01-01
    • 2011-08-04
    • 2010-11-02
    • 1970-01-01
    相关资源
    最近更新 更多