1 /* 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 /* 9 Compile 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 21 class Program { ceil(double x)22 static int ceil(double x) { return (int)System.Math.Ceiling(x); } convert(double dpi, string path, string out_path)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. try_convert(double dpi, string path, string out_path)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. Main(string[] args)81 static void Main(string[] args) { 82 double dpi = 72.0; 83 if (args.Length == 0) { 84 System.Console.WriteLine("usage:\n\txps_to_png [-dDPI] [XPS_FILES]\n\n"); 85 System.Environment.Exit(1); 86 } 87 System.Collections.Generic.List<string> xpsFiles = 88 new System.Collections.Generic.List<string>(); 89 foreach (string arg in args) { 90 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) { 101 System.Threading.Thread t = new System.Threading.Thread( 102 () => try_convert(dpi, file, file)); 103 t.SetApartmentState(System.Threading.ApartmentState.STA); 104 t.Start(); 105 } 106 } 107 } 108