Что приводит к растеризации вывода на принтер WPF? - PullRequest
7 голосов
/ 09 июня 2011

Я сталкивался со многими проблемами при печати в WPF, когда определенные комбинации печатаемых элементов внезапно вызывают растеризацию вывода на принтер (что приводит к уродливым и огромным выводам на принтер и может привести к тому, что на печать каждой страницы уходит 30 секунд). Я обнаружил, что часто такие вещи, как любой уровень непрозрачности, установленный на элементе управления, вызывают это. Я забыл, что все остальное делает (я верю, что использование холста с включенным отсечением может сделать то же самое), но теперь я сталкиваюсь с еще одной проблемой со стековой панелью с мозаичной кистью для изображений, заполняющей границу ... и т.д .. который теперь снова вызывает эту растеризацию.

Итак, прежде чем я снова начал ковыряться, пытаясь выяснить, что вызывает то, что и т.д., я хотел бы узнать, знает ли кто-нибудь о точном источнике информации о том, какие конкретные элементы могут вызвать это? Или, может быть, каким-то образом подключиться к системе, где это происходит, чтобы я хотя бы попытался это выяснить ...

Это, безусловно, самая печальная часть моих нескольких лет работы в WPF.

обновление: сегодня я обнаружил, что простое включение изображения в холст может привести к его растеризации. Не последовательно, но иногда. Может быть привязан к размеру или, может быть, обрезан ли он и т. Д.

Я часто печатаю в файлы PDF, но я обнаружил почти одинаковое поведение между Adobe Acrobat Printer и другими физическими принтерами.

1 Ответ

8 голосов
/ 21 марта 2012

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

static void Main(string[] args)
{
    var printers = new LocalPrintServer().GetPrintQueues(new[] { EnumeratedPrintQueueTypes.Local, EnumeratedPrintQueueTypes.Connections });
    PrintQueue defaultPrinter = LocalPrintServer.GetDefaultPrintQueue();
    PrintQueue printerToUse = printers.FirstOrDefault(p => p.Name.Contains("PDFCreator")) ?? defaultPrinter; // Use PDFCreator if available.
    PrintTicket ticket = printerToUse.DefaultPrintTicket;
    XpsDocumentWriter writer = PrintQueue.CreateXpsDocumentWriter(printerToUse);
    writer.Write(CreateVisual(), ticket);
}

private static Visual CreateVisual()
{
    var visual = new DrawingVisual();
    using (DrawingContext dc = visual.RenderOpen())
    {
        var pen = new Pen(Brushes.Black, 3);
        var opacityBrush = new SolidColorBrush { Color = Colors.Violet, Opacity = 0.7 };
        dc.PushClip(new RectangleGeometry(new Rect(20, 20, 150, 150)));
        dc.DrawLine(pen, new Point(0, 0), new Point(200, 300));
        dc.DrawEllipse(new SolidColorBrush(Colors.LightGreen), pen, new Point(50, 80), 50, 70);
        dc.DrawRectangle(new SolidColorBrush(Colors.LightBlue), pen, new Rect(10, 100, 100, 100));
        dc.DrawRectangle(new SolidColorBrush(Colors.LightPink), pen, new Rect(40, 120, 100, 100));
        dc.DrawRectangle(new SolidColorBrush(Colors.LightGray), pen, new Rect(60, 140, 100, 100));
        dc.DrawRectangle(opacityBrush, pen, new Rect(80, 160, 100, 100));
    }

    return visual;
}

Полное тестовое приложение можно загрузить с здесь (решение VS 2010).

Во время тестирования я печатаю на PDFCreator , виртуальном PDF-принтере для предотвращения массового использования бумаги. Но я получаю тот же результат с реальными физическими принтерами. Однако на этом примере трудно заметить разницу на бумаге, однако случаи реального мира могут быть более заметными ( pic1 , pic2 ).

Вот скриншот с результатом: wpf printing rasterization testapp result При увеличении PDF-файла вы видите, что прямоугольники и эллипсы больше не имеют векторного формата и становятся размытыми.


Условия растеризации

Кажется, это очень сложно определить. Я поделился тем же опытом, что и Boomhauer, что непрозрачность и отсечение, кажется, довольно часто вызывают растеризацию. И мой пример действительно включает в себя оба из них (вроде того, которые использовались специально при попытке инициировать растеризацию). Не сказать, что любой из них должен присутствовать для растеризации.

Имеет смысл, что непрозрачность может вызвать растеризацию, но некоторые другие тонкие изменения, которые, по вашему мнению, не имеют отношения к проблеме, могут фактически "предотвратить" растеризацию. Как изменение толщины пера в моем примере ( снимок экрана ). Другие изменения, которые каким-то образом удаляют условие растеризации, - это изменение порядка операций рисования, удаление любых операций и, конечно, удаление непрозрачности или отсечения.

Обход

Я обнаружил, что создание файла XPS и его печать из Microsoft XPS Viewer фактически приведет к выводу без растрового изображения, даже если используется точно такой же чертеж и принтер.

private static void GenerateXps()
{
    var xpsDoc = new XpsDocument("wpf_printing_raster_test.xps", FileAccess.ReadWrite);
    XpsDocumentWriter writer = XpsDocument.CreateXpsDocumentWriter(xpsDoc);
    writer.Write(CreateVisual());
    xpsDoc.Close();
}

Скриншот здесь .

Таким образом, вместо печати непосредственно из вашего кода, вы можете сгенерировать XPS-оч, а затем программно дать команду Microsoft XPS Viewer напечатать XPS для вас.

Это, конечно, хакерский и не оптимальное решение. Но мне было бы интересно, если у кого-нибудь есть хороший метод принуждения к печати из Microsoft XPS Viewer, если не найдено никакого исправления или реального решения (я еще не пробовал сам).

Мне также было бы интересно узнать, есть ли у кого-нибудь растеризованные распечатки даже при печати из Microsoft XPS Viewer.

В общем, я попытался загрузить XPS-файл в мое тестовое приложение и распечатать его ( код ). Но это не сработало, все равно получил растеризованную распечатку.

Решение

Не думаю, что это проблема с драйвером принтера. Когда происходит растеризация, она происходит на всех принтерах без исключения. Я пробовал 4-5 различных принтеров, от 100 HP 1020 до 6000 Konica Minolta C360 за несколько долларов и несколько виртуальных принтеров.

Обходной путь также указывает, что Microsoft XPS Viewer отправляет что-то другое в драйвер принтера, чем прямая печать WPF.

Мы должны действительно попытаться заставить Microsoft взглянуть на это, оно было зарегистрировано как bug еще в 2009 году, но ничего не произошло. Надеюсь, небольшой пример кода для воспроизведения проблемы поможет.

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