Подтвердить что ты не робот

WPF RenderTargetBitmap Отсутствующие элементы

У меня есть TreeView с маленькими значками, отображаемыми в шаблоне данных. Я пытаюсь сохранить Treeview как PNG, используя RenderTargetBitmap.

Изображение сохранено правильно на небольших наборах данных. Однако, если набор данных становится слишком большим, некоторые значки исключаются из окончательного изображения. Кажется, что волшебное число 200 предметов. Кажется, не имеет значения, является ли дерево глубоким или широким, после 200 предметов значки не отображаются.

Добавлен код

Итак, вот мой код, который я использую для создания изображения.

        RenderTargetBitmap targetBitmap = new RenderTargetBitmap(
            (int)_treeView.ActualWidth,
            (int)_treeView.ActualHeight,
            96, 96, PixelFormats.Default);

        targetBitmap.Render(_treeView);

Добавлен экранный снимок

Обратите внимание на недостающие значки в правой части дерева. Снимок экрана с отсутствующими значками

Теперь, если я скрою несколько ветвей, скрывая некоторые из других значков, эти значки включены. Это почти похоже на RenderTargetBitmap.Render не имеет возможности отображать все значки. Или это может иметь какое-то отношение к виртуальным панелям. Снимок экрана с включенными значками

Вот более пристальный взгляд. введите описание изображения здесь

4b9b3361

Ответ 1

Что я сразу заметил, что у вас ОГРОМНОЕ изображение. Ширина 12000. Я удивлен, что ты даже получил это близко.

Как указано в MSDN, ширина/высота текстуры ограничены ограничениями текстуры DirectX.

Максимально отображаемый размер визуального дерева XAML ограничен максимальными размерами текстуры Microsoft DirectX; для получения дополнительной информации см. "Ограничения ресурсов" (Direct3D). Это ограничение может варьироваться в зависимости от аппаратного обеспечения приложения. Очень большой контент, превышающий этот предел, может быть масштабирован для соответствия. Если ограничения масштабирования применяются таким образом, размер рендеринга после масштабирования может быть запрошен с использованием свойств PixelWidth и PixelHeight. Например, визуальное дерево XAML размером 10000 на 10000 пикселей может быть масштабировано до 4096 на 4096 пикселей, что является примером конкретного ограничения, вызванного аппаратным обеспечением, на котором работает приложение. http://msdn.microsoft.com/library/windows/apps/dn298548

Я подозреваю следующее:

  • Виртуализация отключает некоторые вещи. У меня была последняя проблема с DataGrid, и проблема была в виртуализации. Ваше дело не похоже на одно.
  • Слишком большая текстура может вызвать поведение undefined.

Вы можете попробовать отключить аппаратное ускорение. Эта вещь вызывает довольно много хардкорных ошибок. http://msdn.microsoft.com/en-us/library/system.windows.media.renderoptions.processrendermode.aspx

Кроме этого - это будет сложно, но я уверен, что он будет работать красиво:

1) начинайте с корневого объекта и рекурсивно переходите к корневым объектам, пока не найдете объект размером менее 1000 х 1000. Сфотографируйте его с помощью RenderTargetBitmap (BMP) и объедините его в IN-MEMORY-BMP, Сделайте это для каждого ребенка.

Вы должны уметь вычислять все это.

Ответ 2

Для записей: существует обходное решение.

Вместо визуализации непосредственно с помощью RenderTargetBitmap используйте временный DrawingVisual. Покрасьте свой Visual в DrawingVisual с помощью VisualBrush, а затем используйте RenderTargetBitmap с DrawingVisual.

Вот так:

    public BitmapSource RenderVisualToBitmap(Visual visual)
    {
        var contentBounds = VisualTreeHelper.GetContentBounds(visual);

        var drawingVisual = new DrawingVisual();
        using (var drawingContext = drawingVisual.RenderOpen())
        {
            var visualBrush = new VisualBrush(visual);
            drawingContext.DrawRectangle(visualBrush, null, contentBounds);
        }

        var renderTargetBitmap = new RenderTargetBitmap((int)contentBounds.Width, (int)contentBounds.Height, 96, 96, PixelFormats.Default);
        renderTargetBitmap.Render(drawingVisual);

        return renderTargetBitmap;
    }

Обратите внимание, однако, что по мере увеличения вашего VisualBrush результирующее изображение становится все более и более нечетким (при рендеринге с высоким DPI). Чтобы обойти эту проблему, используйте серию небольших фрагментов VisualBrush, как описано здесь: https://srndolha.wordpress.com/2012/10/16/exported-drawingvisual-quality-when-using-visualbrush/