X-Ray.PS
26.10.7019
dotnet add package X-Ray.PS --version 26.10.7019
NuGet\Install-Package X-Ray.PS -Version 26.10.7019
<PackageReference Include="X-Ray.PS" Version="26.10.7019" />
<PackageVersion Include="X-Ray.PS" Version="26.10.7019" />
<PackageReference Include="X-Ray.PS" />
paket add X-Ray.PS --version 26.10.7019
#r "nuget: X-Ray.PS, 26.10.7019"
#:package X-Ray.PS@26.10.7019
#addin nuget:?package=X-Ray.PS&version=26.10.7019
#tool nuget:?package=X-Ray.PS&version=26.10.7019
X-Ray.PS

Reads PostScript, Encapsulated PostScript and XPS documents and converts them to PDF and raster images, in pure managed C#. Part of the X-Ray family of .NET document libraries; documentation at https://xray.curiosity.ai/.
X-Ray.PS is a port of an MIT-licensed open-source Python PostScript/XPS library. It contains a
PostScript interpreter, an XPS reader and writer, a render model shared by both inputs, a PDF
writer with font embedding, and a raster renderer with PNG, JPEG, BMP and TIFF encoders. The core
package has no native dependencies. X-Ray.PS.Skia is an optional add-on that draws pages with
SkiaSharp instead, which reproduces the original library's default raster output.
Install
dotnet add package X-Ray.PS
dotnet add package X-Ray.PS.Skia # optional: SkiaSharp raster output
Quick start
using XRay.PS;
using XRay.PS.PostScript;
using XRay.PS.Xps;
// PostScript or EPS to PDF and PNG
var ps = PsDocument.FromFile("drawing.ps");
File.WriteAllBytes("drawing.pdf", ps.ToPdf());
File.WriteAllBytes("drawing.png", ps.ToImage(new ImageSaveOptions(ImageFormat.Png, dpi: 150)));
// XPS to PDF, and one image per page
var xps = XpsDocument.FromFile("report.xps");
File.WriteAllBytes("report.pdf", xps.ToPdf());
List<byte[]> pages = xps.ToImages(new ImageSaveOptions(ImageFormat.Png, dpi: 96));
// Build and edit documents
var doc = PsDocument.Create(isEps: true, width: 200, height: 100);
doc.GetPage(0).Canvas.DrawText("Hello", 10, 10, "Helvetica", 12);
File.WriteAllBytes("hello.eps", doc.Save());
// Wrap a PNG, JPEG, BMP or TIFF in EPS
File.WriteAllBytes("logo.eps", ImageToEps.ConvertFile("logo.png"));
Streams, cancellation, limits and recovery
Every conversion also takes a CancellationToken (last parameter) and has overloads that write to
a stream, so a large PDF never exists as one array:
using var token = new CancellationTokenSource(TimeSpan.FromSeconds(60));
var options = new PdfSaveOptions
{
JpegQuality = 75, // re-encode raw 8-bit gray/RGB images as JPEG when that is smaller
SuppressErrors = true, // keep what was drawn, record a warning, go on after the next showpage
Limits = new PsInterpreterLimits { MaxOperators = 50_000_000 },
};
using var file = File.Create("drawing.pdf");
PsDocument.FromFile("drawing.ps", token.Token).ToPdf(file, options, token.Token);
foreach (var warning in options.Warnings)
Console.WriteLine($"{warning.Source} {warning.Code}: {warning.Message}");
// XPS: the same, with an optional page limit
XpsDocument.FromFile("report.xps", token.Token).ToPdf(file, options, maxPages: 50, token.Token);
// One stream per page
xps.ToImages(new ImageSaveOptions(ImageFormat.Png), page => File.Create($"page{page + 1}.png"), null, token.Token);
PostScript is a programming language, so a hostile file can loop forever or ask for gigabytes.
The interpreter polls the token, and PsInterpreterLimits bound it even without one: executed
objects (400 million by default), operand stack depth, procedure nesting, source nesting and
memory. A cancelled call throws OperationCanceledException (never turned into a warning); an
exceeded limit throws PsResourceLimitError, which stopped does not catch.
Fonts: standard PostScript names resolve to the bundled Liberation Serif and Dingbats fonts or to
fonts installed on the system. Set AdditionalFontsFolder on the save options to add a folder.
A render model (BuildRenderModel) is available for both input kinds.
Differences from the Python original
- The raster output of
RenderModelRasterWriteris the original's pure-Python renderer, ported pixel for pixel. The original's default writer is Skia;X-Ray.PS.Skiaprovides that. - JPEG XR images are not decoded (the original needs an optional codec for them too).
- ICC-profile colors in XPS (
ContextColor) use the original's fallback formula.
License
MIT, see LICENSE. Bundled fonts and the ICC profile carry their own licences, listed in NOTICE.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- No dependencies.
NuGet packages (2)
Showing the top 2 NuGet packages that depend on X-Ray.PS:
| Package | Downloads |
|---|---|
|
X-Ray.PS.Skia
SkiaSharp raster writer for X-Ray.PS: anti-aliased PostScript, EPS and XPS rendering with gradients, opacity, image brushes and font rasterization, matching the default output of the library X-Ray.PS was ported from. |
|
|
X-Ray
The umbrella package for the X-Ray family of .NET libraries. Carries no code of its own: installing it brings in every X-Ray package, for content extraction (X-Ray.Content), rendering office documents to PDF and images (X-Ray.Office), and reading Photoshop (X-Ray.Psd), email (X-Ray.Email), iCalendar (X-Ray.Ics), PostScript and XPS (X-Ray.PS) and OneNote (X-Ray.OneNote) files. Install a single member directly if you only need one. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 26.10.7019 | 0 | 10/19/2026 |
| 26.10.6966 | 6 | 10/19/2026 |