Использование RenderTargetBitmap в WindowsFormsHost - PullRequest
4 голосов
/ 18 ноября 2009

У меня есть набор элементов управления внутри WindowsFormsHost, и я хотел бы захватить текущий вид и просто сохранить его как изображение, однако я получаю только несколько Panel видимых на изображении.

Можно ли использовать WindowsFormsHost в качестве «визуального» и захватывать упакованные элементы управления?

См. Мой пример:

<WindowsFormsHost x:Name="windowHost">
    <wf:Panel Dock="Fill" x:Name="basePanel"/>
</WindowsFormsHost>

Если бы я добавил кнопку или что-то еще в basePanel, это не было бы видно при экспорте в PNG со следующим кодом:

 RenderTargetBitmap rtb = new RenderTargetBitmap(basePanel.Width, 
                                 basePanel.Height, 96, 96, PixelFormats.Pbgra32);
 rtb.Render(windowHost);

 PngBitmapEncoder pnge = new PngBitmapEncoder();
 pnge.Frames.Add(BitmapFrame.Create(rtb));
 Stream stream = File.Create("test.jpg");

 pnge.Save(stream);

 stream.Close();

Предложения о том, почему это может не сработать и, возможно, возможный обходной путь? Я думаю, это не совсем так, но можно надеяться!

Ответы [ 2 ]

6 голосов
/ 18 ноября 2009

Содержимое WindowsFormsHost отображается с помощью GDI +, как в приложении Windows Forms, поэтому вы не можете использовать RenderTargetBitmap для этого, так как он не отображается WPF. Вместо этого вы должны использовать функцию GDI + BitBlt, которая позволяет вам делать снимки области на экране.

См. этот пост для примера


ОБНОВЛЕНИЕ: вот еще одна версия кода, обновленная для использования с WPF:

using System.Drawing;
...

public static ImageSource Capture(IWin32Window w)
{
    IntPtr hwnd = new WindowInteropHelper(w).Handle;
    IntPtr hDC = GetDC(hwnd);
    if (hDC != IntPtr.Zero)
    {
        Rectangle rect = GetWindowRectangle(hwnd);
        Bitmap bmp = new Bitmap(rect.Width, rect.Height);
        using (Graphics destGraphics = Graphics.FromImage(bmp))
        {
            BitBlt(
                destGraphics.GetHdc(),
                0,
                0,
                rect.Width,
                rect.Height,
                hDC,
                0,
                0,
                TernaryRasterOperations.SRCCOPY);
        }
        ImageSource img = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
            bmp.GetHBitmap(),
            IntPtr.Zero,
            Int32Rect.Empty,
            BitmapSizeOptions.FromEmptyOptions());
        return img;
    }
    return null;
}

Просто позвоните и передайте элемент управления WindowsFormsHost в качестве параметра методу Capture и сделайте все, что захотите, с полученным ImageSource. Для определения BitBlt и GetDC, посмотрите на этот веб-сайт (я написал это на своем домашнем компьютере, к которому я не могу получить доступ с того места, где я сейчас нахожусь)

4 голосов
/ 18 ноября 2009

Элемент управления Windows Forms также знает, как визуализировать себя, вам не нужно прыгать через обруч захвата экрана. Сделайте так, чтобы это выглядело так:

    using (var bmp = new System.Drawing.Bitmap(basePanel.Width, basePanel.Height)) {
        basePanel.DrawToBitmap(bmp, new System.Drawing.Rectangle(0, 0, bmp.Width, bmp.Height));
        bmp.Save(@"c:\temp\test.png");
    }
...