2012-04-17 51 views
0

我遇到了一個問題,我使用此代碼將水印應用於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並向其添加Document順序(在添加和縮放水印之後)。

之後,嵌入式XpsImage是一個1x1黑色像素......大概是因爲我需要複製資源(感謝Jon)。

關於我如何完成此操作的任何建議?

感謝

回答

0

你應該添加水印後添加fixedPage.UpdateLayout()。

0

它看起來像你跳過複製所有的資源和打印票。一般來說,您應該嘗試修改現有文檔,而不是創建一個新副本。

+0

這是問題所在。新的Xps引用了一個PNG圖像(XpsImage),但它是一個1px x 1px的黑色圖像。我縮小了它的範圍,這在我最初發布的AddWatermark方法中並沒有明顯的發生,但是通過對xps進行重新序列化而非常簡單。你能否就我如何「複製」資源(我已更新問題)給出任何建議。謝謝。 – sambomartin 2012-04-17 15:05:14

+0

@sambomartin是否有一些原因是您試圖複製文檔而不是修改現有文檔?據推測,你可以簡單地將水印內容添加到FixedPage的Children集合中。另一方面,如果您的水印只是一個字符串,爲什麼不使用printticket的PageWatermark功能? – Jon 2012-04-17 16:23:58

+0

PageWatermark屬性聽起來不錯。我會研究它。 tbh我只涉及使用XPS從WPF打印,所以歡迎任何建議。謝謝 – sambomartin 2012-04-17 20:18:34