【问题标题】:WPF Screenshot JPG from UIElement with C#使用 C# 来自 UIElement 的 WPF 屏幕截图 JPG
【发布时间】:2010-06-04 20:02:08
【问题描述】:

我正在尝试从我的 WPF 应用程序的一部分创建 JPG。像截图一样,仅限个人UIElements。我从这里开始:http://www.grumpydev.com/2009/01/03/taking-wpf-screenshots/

我正在使用他的扩展方法,它允许您使用UIElement.GetJpgImage() 获得一个字节[]。然后可以使用文件流将其写入 JPG 图像。如果我制作整个窗口的 JPG,它看起来就好了!然而,这并不理想,因为它只是捕捉用户所看到的。由于滚动查看器或由于其父对象被动画到小尺寸而不可见的事物将不会显示。

如果我对用于布局的网格进行“截图”: alt text http://img697.imageshack.us/img697/4233/fullscreenshot2.jpg

我得到了这个黑色背景的废话。我不想那样。此外,如果我使用动画折叠了这个网格的高度,我将一无所获。这些实际上是模板复选框,它们上面应该有黑色文本,并且网格的背景应该是白色的。这是其他人编写的用于返回写入文件流的 byte[] 数组的代码:

public static byte[] GetJpgImage(this UIElement source, double scale, int quality)
{
    double actualHeight = source.RenderSize.Height;
    double actualWidth = source.RenderSize.Width;

    double renderHeight = actualHeight * scale;
    double renderWidth = actualWidth * scale;

    RenderTargetBitmap renderTarget = new RenderTargetBitmap((int) renderWidth, (int) renderHeight, 96, 96, PixelFormats.Pbgra32);
    VisualBrush sourceBrush = new VisualBrush(source);

    DrawingVisual drawingVisual = new DrawingVisual();
    DrawingContext drawingContext = drawingVisual.RenderOpen();

    using (drawingContext)
    {
        drawingContext.PushTransform(new ScaleTransform(scale, scale));
        drawingContext.DrawRectangle(sourceBrush, null, new Rect(new Point(0, 0), new Point(actualWidth, actualHeight)));
    }
    renderTarget.Render(drawingVisual);

    JpegBitmapEncoder jpgEncoder = new JpegBitmapEncoder();
    jpgEncoder.QualityLevel = quality;
    jpgEncoder.Frames.Add(BitmapFrame.Create(renderTarget));

    Byte[] _imageArray;

    using (MemoryStream outputStream = new MemoryStream())
    {
        jpgEncoder.Save(outputStream);
        _imageArray = outputStream.ToArray();
    }

    return _imageArray;
}

在那里的某个地方,我们得到了黑色背景。有什么见解吗?

编辑:如果我将网格的背景属性设置为白色,屏幕截图会按预期显示。但是,设置我需要截屏的所有内容的背景是不可行的。

【问题讨论】:

    标签: c# wpf wpf-controls screenshot uielement


    【解决方案1】:

    只是一个猜测,我认为黑色背景将代表字节数组的一部分,这些部分在此过程中未设置为任何内容。数组中的初始零将显示为黑色。

    为避免这种情况,我建议使用 0xFF (byte.MaxValue) 值初始化数组。

    更新:

    仔细观察,我认为您应该在渲染 UI 元素之前在图像上绘制一个白色矩形。无论如何,这应该可以工作。

    就在这行代码之前

    drawingContext.DrawRectangle(sourceBrush, null, new Rect(new Point(0, 0), new Point(actualWidth, actualHeight))); 
    

    放这样的东西

    drawingContext.DrawRectangle(Brushes.White, null, new Rect(new Point(0, 0), new Point(actualWidth, actualHeight))); 
    

    【讨论】:

    • 当数组被“_imageArray = outputStream.ToArray();”填充时,我该怎么做?
    • 我觉得不只是黑色,可能是透明黑色(保存到png可以快速检查)。因此,您可以在所需的背景上绘制图像并保存生成的图像。
    • 如果它是透明的黑色,正如@max 所建议的那样,那么您可以只扫描字节数组,为每个在 alpha 通道中为零的像素设置颜色。
    • Jeffrey - 我不知道该怎么做...我对 JPG 或字节如何描述它们的了解为零。
    • @Adam S - 我刚刚添加了一些可能有帮助的(未尝试过的)代码。希望对您有所帮助!
    【解决方案2】:

    不幸的是,唯一有效的方法就是在 XAML 中设置元素的背景。我不想这样做,但我想这是我在这种情况下需要做的。无论如何感谢您的建议。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-03
      • 1970-01-01
      • 2010-12-23
      • 2011-03-28
      • 2011-02-17
      相关资源
      最近更新 更多