blob: 738e0fc17e5946c6fdb0930ec42a31b6c687e501 [file] [log] [blame]
/*
* Copyright 2016 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
/*
Compile with:
"...../csc" \
/lib:"....." \
/reference:"ReachFramework.dll" \
/reference:"WindowsBase.dll" \
/reference:"PresentationCore.dll" \
/reference:"PresentationFramework.dll" \
xps_to_png.cs
*/
// logic inspired by this example: https://goo.gl/nCxrjQ
class Program {
static int ceil(double x) { return (int)System.Math.Ceiling(x); }
static void convert(double dpi, string path, string out_path) {
double scale = dpi / 96.0;
System.Windows.Xps.Packaging.XpsDocument xpsDoc =
new System.Windows.Xps.Packaging.XpsDocument(
path, System.IO.FileAccess.Read);
if (xpsDoc == null) {
throw new System.Exception("XpsDocumentfailed");
}
System.Windows.Documents.FixedDocumentSequence docSeq =
xpsDoc.GetFixedDocumentSequence();
if (docSeq == null) {
throw new System.Exception("GetFixedDocumentSequence failed");
}
System.Windows.Documents.DocumentReferenceCollection drc = docSeq.References;
int index = 0;
foreach (System.Windows.Documents.DocumentReference dr in drc) {
System.Windows.Documents.FixedDocument dp = dr.GetDocument(false);
foreach (System.Windows.Documents.PageContent pc in dp.Pages) {
System.Windows.Documents.FixedPage fixedPage = pc.GetPageRoot(false);
double width = fixedPage.Width;
double height = fixedPage.Height;
System.Windows.Size sz = new System.Windows.Size(width, height);
fixedPage.Measure(sz);
fixedPage.Arrange(
new System.Windows.Rect(new System.Windows.Point(), sz));
fixedPage.UpdateLayout();
System.Windows.Media.Imaging.BitmapImage bitmap =
new System.Windows.Media.Imaging.BitmapImage();
System.Windows.Media.Imaging.RenderTargetBitmap renderTarget =
new System.Windows.Media.Imaging.RenderTargetBitmap(
ceil(scale * width), ceil(scale * height), dpi, dpi,
System.Windows.Media.PixelFormats.Default);
renderTarget.Render(fixedPage);
System.Windows.Media.Imaging.BitmapEncoder encoder =
new System.Windows.Media.Imaging.PngBitmapEncoder();
encoder.Frames.Add(
System.Windows.Media.Imaging.BitmapFrame.Create(renderTarget));
string filename = string.Format("{0}_{1}.png", out_path, index);
System.IO.FileStream pageOutStream = new System.IO.FileStream(
filename, System.IO.FileMode.Create, System.IO.FileAccess.Write);
encoder.Save(pageOutStream);
pageOutStream.Close();
System.Console.WriteLine(filename);
++index;
}
}
}
// Executes convert, catching thrown exceptions, and printing them
// to stdout, and exiting immediately.
static void try_convert(double dpi, string path, string out_path) {
try {
convert(dpi, path, out_path);
} catch (System.Exception e) {
System.Console.WriteLine(e);
System.Environment.Exit(1);
}
}
// For each command line argument, convert xps to sequence of pngs.
static void Main(string[] args) {
double dpi = 72.0;
if (args.Length == 0) {
System.Console.WriteLine("usage:\n\txps_to_png [-dDPI] [XPS_FILES]\n\n");
System.Environment.Exit(1);
}
System.Collections.Generic.List<string> xpsFiles =
new System.Collections.Generic.List<string>();
foreach (string arg in args) {
string flag = "-d";
if (arg.StartsWith(flag)) {
dpi = System.Convert.ToDouble(arg.Remove(0, flag.Length));
} else if (System.IO.File.Exists(arg)) {
xpsFiles.Add(arg);
} else {
System.Console.WriteLine("file missing: '" + arg + "'\n\n");
System.Environment.Exit(1);
}
}
foreach (string file in xpsFiles) {
System.Threading.Thread t = new System.Threading.Thread(
() => try_convert(dpi, file, file));
t.SetApartmentState(System.Threading.ApartmentState.STA);
t.Start();
}
}
}