Modifying XPS Document: Add Watermark
Windows Platform Foundation has provided easy APIs and solutions for XPS document generation, visualization and printing. But often time, after XPS documents are generated, we would like to modify it in certain way. The scenario I'm trying to demonstrate here is adding a watermark to each page within an XPS document.
There are multiple ways to modify an XPS document. The lowest level would be working from container and XPS markup directly. But if you're changing font/image resources, it can get quite complicated.
Another way is using WPF to load each page in an XPS document as a Visual, modify the Visual, and then write it back as a new XPS document. We will take the second approach here.
The first step is to create a Visual for watermak:
Visual CreateWatermark(double width, double height, string message){ DrawingVisual watermark = new DrawingVisual(); using (DrawingContext ctx = watermark.RenderOpen()) { FormattedText text = new FormattedText(message, System.Globalization.CultureInfo.CurrentCulture, FlowDirection.LeftToRight, new Typeface("Times New Roman"), 96 * 1.5, new SolidColorBrush(Color.FromScRgb(0.3f, 1f, 0f, 0f)) ); // Rotate transform, keep center { double diag = Math.Sqrt(width * width + height * height); double cX = width / 2; double cY = height / 2; double sin = height / diag; double cos = width / diag; double dx = (cX * (1.0 - cos)) + (cY * sin); double dy = (cY * (1.0 - cos)) - (cX * sin); Transform mat = new MatrixTransform(cos, sin, -sin, cos, dx, dy); ctx.PushTransform(mat); } // Centerlize double x = (width - text.Width) / 2; double y = (height - text.Height) / 2; ctx.DrawText(text, new Point(x, y)); ctx.Pop(); } return watermark;}
The CreateWatermark routine accepts three parameters, page width, page height, and a text string. It creates a DrawingVisual by drawing to the DrawingContext interface. To make it more like a real watermark, text is rotated according to page dimension and centered.
Once we have code for watermark, we can use XPS-related API to load a document and create a new document:
void AddWatermark(string filename){ // Open original XPS document XpsDocument xpsOld = new XpsDocument(filename, FileAccess.Read); FixedDocumentSequence seqOld = xpsOld.GetFixedDocumentSequence(); // Create new XPS document Package container = Package.Open("new_" + filename, FileMode.Create); XpsDocumentWriter writer = XpsDocument.CreateXpsDocumentWriter(new XpsDocument(container)); // 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); newpage.Children.Add(CreateWatermark(width, height, "Confidential (" + pageno + ")")); pageno ++; // Write out modified page vxpsd.Write(newpage); } } vxpsd.EndBatchWrite(); container.Close(); xpsOld.Close();}
There are a few things to notice here:
- SerializerWriteCollator is used to write multiple Visuals out, each as a FixedPage
- Measure, Arrange, and UpdateLayout are used to convert FixedPage to a WPF Visual.
- ContainerVisual is used to combine the original page with the watermark.
- The contains of the document is re-serialized, so markup and resource may not be the same as in original document.
Finally, here is a sample output:
Comments
Anonymous
September 06, 2006
Cool site! Thanks!
<a href="http://topperfumes.free20.com/topperfumes/lancome-perfume.html">lancome perfume</a> <a href="http:// topperfumes.free20.com/topperfumes/womens-perfume.html ">womens perfume</a>
[url=http:// topperfumes.free20.com/topperfumes/dolce-gabbana-perfume.html ]dolce gabbana perfume[/url] [url=http:// topperfumes.free20.com/topperfumes/perfume-oil.html ]perfume oil[/url]Anonymous
September 12, 2006
istalacion de programaAnonymous
December 02, 2006
This sample DOES NOT work for landscape pages!! How can this be done for landscape???Anonymous
January 08, 2007
Thank you for your explanation. But I have another question. Now our team want to develop XPS printer driver for our OEM products. The sample of XPS driver in Vista DDK is written based on Unidrv. And I happen to know if we can write similar code for XPS driver to GDI-based monolithic driver. And the new XPS driver does not use any utilities of Unidrv.Anonymous
June 06, 2007
The comment has been removedAnonymous
June 27, 2007
Any solution for the landscape issue?Anonymous
June 27, 2007
Hi, if you want to have the pages in correct size (also in the xps-viewer) then just add a simple printticket with the PageMediaSize set to the size of the FixedPage... regards, Jo ... // Write out modified page PrintTicket pt = new PrintTicket(); pt.PageMediaSize = new PageMediaSize(width, height); vxpsd.Write(newpage, pt); ...Anonymous
June 28, 2007
for printing you need also the PageOrientation in PrintTicket: ... // Write out modified page PrintTicket pt = new PrintTicket(); pt.PageMediaSize = new PageMediaSize(width, height); pt.PageOrientation = (width > height) ? PageOrientation.Landscape : PageOrientation.Portrait; vxpsd.Write(newpage, pt); ...Anonymous
July 31, 2007
<a href="httpwwwigenqmvhcnpage3html">debrawhalengeorgia</a> debrawhalengeorgia,<a href="httpwwwigenqmvhcnpage4html">matthewstaffordcindynelsonwedding</a> matthewstaffordcindynelsonwedding,<a href="httpwwwigenqmvhcnpage18html">blondesamp</a> blondesamp,<a href="httpwwwigenqmvhcnpage4html">weddingshopslancashire</a> weddingshopslancashire,<a href="httpwwwtyxotwjecnpage98html">tradingspacesideasforbedroomvanitytable</a> tradingspacesideasforbedroomvanitytable,<a href="httpwwwigenqmvhcnpage15html">samsclubmemberbenefits</a> samsclubmemberbenefits,<a href="httpwwwtyxotwjecnpage97html">listofstateswithpowerballjackpotwinners</a> listofstateswithpowerballjackpotwinners,<a href="httpwwwigenqmvhcnpage19html">grillzdirtynellylyrics</a> grillzdirtynellylyrics,<a href="httpwwwigenqmvhcnpage4html">whitetulipweddingbouquets</a> whitetulipweddingbouquets,<a href="httpwwwigenqmvhcnpage18html">funneykidsblondejokes</a> funneykidsblondejokes,Anonymous
July 31, 2007
<a href="httpwwwevzvhqkucnpage8html">hotelmayfairpaphoscyprus</a> hotelmayfairpaphoscyprus,<a href="httpwwwevzvhqkucnpage12html">antiquebusinessesamp</a> antiquebusinessesamp,<a href="httpwwwihamuicscnpage98html">vendre</a> vendre,<a href="httpwwwevzvhqkucnpage12html">owningadeli</a> owningadeli,<a href="httpwwwihamuicscnpage92html">gigabeatos</a> gigabeatos,<a href="httpwwwevzvhqkucnpage12html">owningahomeincanaga</a> owningahomeincanaga,<a href="httpwwwevzvhqkucnpage13html">vanhelsingwerewolfpictures</a> vanhelsingwerewolfpictures,<a href="httpwwwevzvhqkucnpage6html">caribbeanflavoredchewsticks</a> caribbeanflavoredchewsticks,<a href="httpwwwihamuicscnpage92html">osuruguay</a> osuruguay,<a href="httpwwwevzvhqkucnpage13html">livingnightmarewerewolfmakeupkit</a> livingnightmarewerewolfmakeupkit,Anonymous
August 01, 2007
<a href="httpwwwyleaqeaacnpage59html">girlsuseingdildos</a> girlsuseingdildos,<a href="httpwwwyleaqeaacnpage47html">saru14deviantart</a> saru14deviantart,<a href="httpwwwyleaqeaacnpage41html">fiskclarkflagghaberdasherfirm</a> fiskclarkflagghaberdasherfirm,<a href="httpwwwyleaqeaacnpage61html">madonnakissingbritny</a> madonnakissingbritny,<a href="httpwwwyleaqeaacnpage55html">forchheim</a> forchheim,<a href="httpwwwyleaqeaacnpage61html">winmadonnaticket</a> winmadonnaticket,<a href="httpwwwyleaqeaacnpage44html">fujis5000camera</a> fujis5000camera,<a href="httpwwwyleaqeaacnpage42html">1967classicvwsale</a> 1967classicvwsale,<a href="httpwwwyleaqeaacnpage40html">glittergraphis</a> glittergraphis,<a href="httpwwwyleaqeaacnpage43html">listofshrubsforacottagegarden</a> listofshrubsforacottagegarden,Anonymous
September 05, 2007
Great snippet... ?? How to write to FixedDocumentSequence rather than to a file [vxpsd.Write(newpage);]Anonymous
November 26, 2007
PingBack from http://feeds.maxblog.eu/item_996524.htmlAnonymous
June 11, 2008
How do you modify the contents on each page?Anonymous
August 11, 2008
PingBack from http://hoursfunnywallpaper.cn/?p=916Anonymous
December 04, 2008
Through scuttlebutt at work I hear various discussions about watermarking and its place in the rightsAnonymous
January 20, 2009
PingBack from http://www.hilpers.com/1031485-nachtraegliches-aendern-von-xps-dateienAnonymous
May 26, 2009
PingBack from http://castironbakeware.info/story.php?title=feng-yuan-modifying-xps-document-add-watermarkAnonymous
June 07, 2009
PingBack from http://greenteafatburner.info/story.php?id=3728Anonymous
June 16, 2009
PingBack from http://lowcostcarinsurances.info/story.php?id=6085Anonymous
June 06, 2010
Fragranceglamour's Beauty products and cosmetics have been used since the Egyptians and Ancient Greece and Rome. Beauty products are not essential, but they are a luxury that most of us can afford. Beauty products range from skin care products such as soaps, bath salts, creams, exfoliating scrubs, and face and body packs, to hair care products such as shampoos, conditioners, hair colours, and various perming solutions, to overall body-care products such as moisturizers