Скриншот WPF JPG от UIElement с C # - PullRequest
4 голосов
/ 05 июня 2010

Я пытаюсь создать JPG из части моих приложений WPF. Как скриншот, только отдельных UIElement с. Я начал здесь: http://www.grumpydev.com/2009/01/03/taking-wpf-screenshots/

Я использую его метод расширения, который существенно позволяет получить байт [] с UIElement.GetJpgImage(). Затем это может быть записано с использованием файлового потока в изображение JPG. Если я сделаю JPG из всего окна, оно выглядит просто отлично! Тем не менее, это не идеально, потому что он просто отражает то, что видит пользователь. Вещи, которые не видны из-за средства просмотра прокрутки или из-за того, что их родительский объект был анимирован до небольшого размера, не будут отображаться.

Если я возьму «скриншот», скажем, сетки, которую я использую для макета: альтернативный текст 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;
}

Где-то там у нас черный фон. Любое понимание?

РЕДАКТИРОВАТЬ: Если я установил свойство фона сетки на белый, снимок экрана, как и ожидалось. Однако установить фон для всего, что мне нужно, чтобы сделать снимок экрана, не представляется возможным.

Ответы [ 2 ]

6 голосов
/ 05 июня 2010

Всего лишь предположение, я бы подумал, что черный фон будет представлять части байтового массива, для которых в этом процессе ничего не установлено. Начальные нули в массиве будут выглядеть как черные.

Чтобы избежать этого, я предлагаю инициализировать массив значениями 0xFF (byte.MaxValue).

ОБНОВЛЕНИЕ:

Глядя на это поближе, я думаю, что вы должны нарисовать белый прямоугольник на изображении, прежде чем рендерить элемент пользовательского интерфейса. Это должно работать в любом случае.

Как раз перед этой строкой кода

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))); 
0 голосов
/ 07 июня 2010

К сожалению, единственное, что сработало, это просто задание фона элемента в XAML.Я не хотел этого делать, но, думаю, это то, что мне нужно сделать в этом случае.В любом случае спасибо за предложение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...