Получить растровое изображение из представления управления - PullRequest
19 голосов
/ 26 марта 2010

Я бы хотел "скопировать в буфер обмена", что рисует Control моего WPF приложения на экране. Поэтому мне нужно создать растровое изображение из моего текущего экрана управления.

Есть ли простой способ сделать это?

Заранее спасибо.

Ответы [ 2 ]

33 голосов
/ 26 марта 2010

Я бы не назвал это простым ... но ключевым компонентом является RenderTargetBitmap, который вы можете использовать следующим образом:

RenderTargetBitmap rtb = new RenderTargetBitmap((int)control.ActualWidth, (int)control.ActualHeight, 96, 96, PixelFormats.Pbgra32);
rtb.Render(control);

Что ж, эта часть проста, теперь в RTB хранятся пиксели внутри ... но ваш следующий шаг - поместить это в полезный формат, чтобы поместить его в буфер обмена, и выяснить это может быть грязно ... Есть много классов, связанных с изображениями, которые взаимодействуют друг с другом.

Вот что мы используем для создания System.Drawing.Image, которое, я думаю, вы сможете поместить в буфер обмена.

PngBitmapEncoder png = new PngBitmapEncoder();
png.Frames.Add(BitmapFrame.Create(rtb));
MemoryStream stream = new MemoryStream();
png.Save(stream);
Image image = Image.FromStream(stream);

System.Drawing.Image (изображение формы) не может напрямую взаимодействовать с RenderTargetBitmap (класс WPF), поэтому мы используем MemoryStream для его преобразования.

9 голосов
/ 20 февраля 2015

Если элемент управления, из которого вы пытаетесь создать растровое изображение, находится внутри StackPanel, он не будет работать, вы просто получите пустое изображение.

У Хайме Родригеса есть хороший кусок кода для полученияоб этом в своем блоге :

private static BitmapSource CaptureScreen(Visual target, double dpiX, double dpiY)
{
    if (target == null)
    {
        return null;
    }
    Rect bounds = VisualTreeHelper.GetDescendantBounds(target);
    RenderTargetBitmap rtb = new RenderTargetBitmap((int)(bounds.Width * dpiX / 96.0),
                                                    (int)(bounds.Height * dpiY / 96.0),
                                                    dpiX,
                                                    dpiY,
                                                    PixelFormats.Pbgra32);
    DrawingVisual dv = new DrawingVisual();
    using (DrawingContext ctx = dv.RenderOpen())
    {
        VisualBrush vb = new VisualBrush(target);
        ctx.DrawRectangle(vb, null, new Rect(new Point(), bounds.Size));
    }
    rtb.Render(dv);
    return rtb;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...