Потеря изображения при повторной сериализации документа XPS

У меня возникла проблема, из-за которой я использую этот код для нанесения водяного знака на каждую страницу в документе XPS.

    private static XpsDocument AddWatermark(string watermark, Package container, XpsDocument xpsOld)
    {
        // Open original XPS document    
        FixedDocumentSequence seqOld = xpsOld.GetFixedDocumentSequence();

        // Create new XPS document
        Uri u = new Uri("pack://TemporaryPackageUri.xps");

        try
        {                
            PackageStore.RemovePackage(u);
        }
        catch { }

        PackageStore.AddPackage(u, container);
        var newdoc = new XpsDocument(container, CompressionOption.Maximum, u.AbsoluteUri);

        XpsDocumentWriter writer = XpsDocument.CreateXpsDocumentWriter(newdoc);

        // Needed for writing multiple pages

        SerializerWriterCollator vxpsd = writer.CreateVisualsCollator();

        int pageno = 1;

        foreach (DocumentReference r in seqOld.References)
        {
            FixedDocument d = r.GetDocument(false);

            // Walk through each page

            foreach (PageContent pc in d.Pages)
            {
                FixedPage fixedPage = pc.GetPageRoot(false);

                double width = fixedPage.Width;
                double height = fixedPage.Height;
                Size sz = new Size(width, height);

                // Convert to WPF Visual

                fixedPage.Measure(sz);
                fixedPage.Arrange(new Rect(new Point(), sz));
                fixedPage.UpdateLayout();

                ContainerVisual newpage = new ContainerVisual();
                newpage.Children.Add(fixedPage);

                if (!string.IsNullOrEmpty(watermark))
                {
                    newpage.Children.Add(CreateWatermark(width, height, watermark + " (" + pageno + ")"));
                }

                pageno++;

                // Write out modified page
                vxpsd.Write(newpage);

            }
        }

        vxpsd.EndBatchWrite();

        container.Flush();

        // this part serializes the doc to a stream so we can get the bytes
        var ms = new MemoryStream();
        var writerx = new XpsSerializerFactory().CreateSerializerWriter(ms);
        writerx.Write(newdoc.GetFixedDocumentSequence());            

        xpsOld.Close();

        return newdoc;
    }

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

У меня проблема в том, что он теряет изображение, встроенное в оригинальный Xps.

Есть что-то, что мне не хватает? как ряд встроенных ресурсов, которые мне нужно скопировать?

Любая помощь приветствуется, я не знаком с документами Xps.

РЕДАКТИРОВАТЬ 1: на самом деле это метод, вызывающий проблему

 public static void PrintFlowDocument(PrintQueue printQueue, DocumentPaginator document, string watermark)
    {
        MemoryStream lMemoryStream = new MemoryStream();
        Package package = Package.Open(lMemoryStream, FileMode.Create);
        Uri u = new Uri("pack://TempTemporaryPackageUri.xps");
        PackageStore.AddPackage(u, package);
        XpsDocument doc = new XpsDocument(package, CompressionOption.NotCompressed, "pack://TempTemporaryPackageUri.xps");

        XpsDocumentWriter xpsDocumentWriter = PrintQueue.CreateXpsDocumentWriter(printQueue);
        xpsDocumentWriter.Write(doc.GetFixedDocumentSequence());          

        PackageStore.RemovePackage(u);
    }

Это функция, которая вызывает (хотя я опустил, чтобы избежать путаницы) функцию addwatermark. Все, что я делаю, это создаю новый xps и добавляю к нему последовательность документов (после добавления и масштабирования водяного знака).

После этого встроенный XpsImage представляет собой черный пиксель размером 1x1... предположительно, поскольку мне нужно скопировать в него ресурсы (спасибо, Джон).

Любые предложения о том, как мне завершить это?

Спасибо


person sambomartin    schedule 17.04.2012    source источник


Ответы (2)


Вы должны добавить fixedPage.UpdateLayout() после добавления водяного знака.

person Ballchris13    schedule 17.04.2012

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

person Jon    schedule 17.04.2012
comment
это проблема. новый XPS имеет ссылку на изображение png (XpsImage), но это черное изображение размером 1px x 1px. Я сузил его, это явно не происходит в методе AddWatermark, который я изначально опубликовал, а довольно просто путем повторной сериализации xps. Можете ли вы дать мне какой-либо совет о том, как вы «скопируете» ресурсы (я обновил вопрос). благодаря. - person sambomartin; 17.04.2012
comment
@sambomartin Есть ли причина, по которой вы пытаетесь скопировать документ, а не изменить существующий? Предположительно, вы можете просто добавить содержимое водяного знака в коллекцию Children FixedPage. С другой стороны, если ваш водяной знак представляет собой не что иное, как строку, почему бы не использовать функцию PageWatermark в билете на печать? - person Jon; 17.04.2012
comment
Свойство PageWatermark звучит хорошо. Я посмотрю на это. tbh Я только баловался печатью из WPF с использованием XPS, поэтому любые советы приветствуются. Благодарность - person sambomartin; 18.04.2012
comment
Можете ли вы привести какие-либо примеры функции PageWatermark? не могу найти много об этом. это свойство .net задания на печать? - person sambomartin; 23.04.2012
comment
Похоже, что PageWatermark не отображается непосредственно в .net. Вам нужно будет открыть XML-файл PrintTicket и изменить его напрямую. Функция PageWatermark определена в спецификации PrintSchema. - person Jon; 23.04.2012