blob: 738e0fc17e5946c6fdb0930ec42a31b6c687e501 [file] [log] [blame]
Hal Canaryc7a46652016-10-17 11:52:40 -04001/*
2 * Copyright 2016 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8/*
9Compile with:
10
11 "...../csc" \
12 /lib:"....." \
13 /reference:"ReachFramework.dll" \
14 /reference:"WindowsBase.dll" \
15 /reference:"PresentationCore.dll" \
16 /reference:"PresentationFramework.dll" \
17 xps_to_png.cs
18
19*/
20// logic inspired by this example: https://goo.gl/nCxrjQ
21class Program {
22 static int ceil(double x) { return (int)System.Math.Ceiling(x); }
23 static void convert(double dpi, string path, string out_path) {
24 double scale = dpi / 96.0;
25 System.Windows.Xps.Packaging.XpsDocument xpsDoc =
26 new System.Windows.Xps.Packaging.XpsDocument(
27 path, System.IO.FileAccess.Read);
28 if (xpsDoc == null) {
29 throw new System.Exception("XpsDocumentfailed");
30 }
31 System.Windows.Documents.FixedDocumentSequence docSeq =
32 xpsDoc.GetFixedDocumentSequence();
33 if (docSeq == null) {
34 throw new System.Exception("GetFixedDocumentSequence failed");
35 }
36 System.Windows.Documents.DocumentReferenceCollection drc = docSeq.References;
37 int index = 0;
38 foreach (System.Windows.Documents.DocumentReference dr in drc) {
39 System.Windows.Documents.FixedDocument dp = dr.GetDocument(false);
40 foreach (System.Windows.Documents.PageContent pc in dp.Pages) {
41 System.Windows.Documents.FixedPage fixedPage = pc.GetPageRoot(false);
42 double width = fixedPage.Width;
43 double height = fixedPage.Height;
44 System.Windows.Size sz = new System.Windows.Size(width, height);
45 fixedPage.Measure(sz);
46 fixedPage.Arrange(
47 new System.Windows.Rect(new System.Windows.Point(), sz));
48 fixedPage.UpdateLayout();
49 System.Windows.Media.Imaging.BitmapImage bitmap =
50 new System.Windows.Media.Imaging.BitmapImage();
51 System.Windows.Media.Imaging.RenderTargetBitmap renderTarget =
52 new System.Windows.Media.Imaging.RenderTargetBitmap(
53 ceil(scale * width), ceil(scale * height), dpi, dpi,
54 System.Windows.Media.PixelFormats.Default);
55 renderTarget.Render(fixedPage);
56 System.Windows.Media.Imaging.BitmapEncoder encoder =
57 new System.Windows.Media.Imaging.PngBitmapEncoder();
58 encoder.Frames.Add(
59 System.Windows.Media.Imaging.BitmapFrame.Create(renderTarget));
60 string filename = string.Format("{0}_{1}.png", out_path, index);
61 System.IO.FileStream pageOutStream = new System.IO.FileStream(
62 filename, System.IO.FileMode.Create, System.IO.FileAccess.Write);
63 encoder.Save(pageOutStream);
64 pageOutStream.Close();
65 System.Console.WriteLine(filename);
66 ++index;
67 }
68 }
69 }
70 // Executes convert, catching thrown exceptions, and printing them
71 // to stdout, and exiting immediately.
72 static void try_convert(double dpi, string path, string out_path) {
73 try {
74 convert(dpi, path, out_path);
75 } catch (System.Exception e) {
76 System.Console.WriteLine(e);
77 System.Environment.Exit(1);
78 }
79 }
80 // For each command line argument, convert xps to sequence of pngs.
81 static void Main(string[] args) {
Hal Canaryc6ca9512016-11-14 10:36:24 -050082 double dpi = 72.0;
Hal Canaryc7a46652016-10-17 11:52:40 -040083 if (args.Length == 0) {
Hal Canaryc6ca9512016-11-14 10:36:24 -050084 System.Console.WriteLine("usage:\n\txps_to_png [-dDPI] [XPS_FILES]\n\n");
Hal Canaryc7a46652016-10-17 11:52:40 -040085 System.Environment.Exit(1);
86 }
Hal Canaryc6ca9512016-11-14 10:36:24 -050087 System.Collections.Generic.List<string> xpsFiles =
88 new System.Collections.Generic.List<string>();
Hal Canaryc7a46652016-10-17 11:52:40 -040089 foreach (string arg in args) {
Hal Canaryc6ca9512016-11-14 10:36:24 -050090 string flag = "-d";
91 if (arg.StartsWith(flag)) {
92 dpi = System.Convert.ToDouble(arg.Remove(0, flag.Length));
93 } else if (System.IO.File.Exists(arg)) {
94 xpsFiles.Add(arg);
95 } else {
96 System.Console.WriteLine("file missing: '" + arg + "'\n\n");
97 System.Environment.Exit(1);
98 }
99 }
100 foreach (string file in xpsFiles) {
Hal Canaryc7a46652016-10-17 11:52:40 -0400101 System.Threading.Thread t = new System.Threading.Thread(
Hal Canaryc6ca9512016-11-14 10:36:24 -0500102 () => try_convert(dpi, file, file));
Hal Canaryc7a46652016-10-17 11:52:40 -0400103 t.SetApartmentState(System.Threading.ApartmentState.STA);
104 t.Start();
105 }
106 }
107}