Modifying XPS Document: Add Watermark
来源:互联网 发布:整容有什么危害知乎 编辑:程序博客网 时间:2024/06/02 20:30
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:
- Modifying XPS Document: Add Watermark
- WaterMark
- Watermark
- watermark
- 无法找到打印机microsoft xps document writer
- Modifying
- xps
- 在Windows 7上使用Microsoft XPS Document Writer无法打印出XPS文档的问题
- c# 调用Microsoft XPS Document Writer打印机,将Pdf文件转换成Xps文件
- powerpoint2007 无法找到打印机“Microsoft XPS Document Writer"
- Printing documents to Microsoft XPS Document Writer without user interaction
- 解决WIN7下添加Microsoft XPS Document Writer
- Power Point 打开显示 "无法找到打印机 Microsoft XPS Document Writer"
- Convert XAML Flow Document to XPS with Style (multiple page, page size, header, margin)
- WaterMark 1.0
- WaterMark TextBox
- c# watermark
- use mongoc add document to mongodb
- iphone 邮箱验证
- hdu 2176 取(m堆)石子游戏
- API函数大全
- 把表导入指定表空的方法
- 用autocad的一点感想
- Modifying XPS Document: Add Watermark
- Linux下检测以太网链路状态代码
- JAVA面向对象基础:成员变量、方法、方法的重载、构造函数
- Builder 模式
- 强化C语言的指针类型学习
- css inline block兼容
- Ibatis 基础配置解说
- Printing documents to Microsoft XPS Document Writer without user interaction
- windows phone 7 启动器