![XPSThumb2.jpg](/KB/files/XPSImage/XPSThumb2.jpg)
Introduction
This application was designed as a proof of concept for generating thumbnails/images from an XPS document.
Background
Recently, I came across a requirement for displaying thumbnails of XPS documents in a SharePoint document library. As a hardcore developer, I'm not in favor of readymade third-party components unless and until you really need them. Hence, I decided to create an image generator myself. I explored the native .NET methods for reading XPS documents. After exploring, I found that in .NET Framework 3.0, there is a managed DLL called ReachFramework.dll, which has all the necessary classes and methods for reading and writing XPS documents.
Classes
Class Diagram
![ClassDiagram.jpg](data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==)
XpsThumbnail Class
This is the one and only class which actually generates the thumbnails from XPS documents using the GenerateThumbnail
method:
converter.GenerateThumbnail();
Properties
Property | Description |
OutputFormat | Output format for the generated image. |
OutputQuality | Quality for the generated image. |
OutputStream | MemoryStream object to be returned. |
XpsFileName | XPS document of which an image needs to be generated. |
Complete Class Listing
public class XpsImage
{
private BitmapEncoder bitmapEncoder = null;
public XpsImage()
{
}
public String XpsFileName { private get; set; }
public OutputFormat OutputFormat {get; set; }
public OutputQuality OutputQuality { private get; set; }
public MemoryStream OutputStream { get; private set; }
public void GenerateThumbnail()
{
XpsDocument xpsDocument =
new XpsDocument(this.XpsFileName, FileAccess.Read);
FixedDocumentSequence documentPageSequence =
xpsDocument.GetFixedDocumentSequence();
string fileNameWithoutExtension =
Path.GetFileNameWithoutExtension(this.XpsFileName);
string fileExtension = string.Empty;
switch (this.OutputFormat)
{
case OutputFormat.Jpeg:
fileExtension = ".jpg";
bitmapEncoder = new JpegBitmapEncoder();
break;
case OutputFormat.Png:
fileExtension = ".png";
bitmapEncoder = new PngBitmapEncoder();
break;
case OutputFormat.Gif:
fileExtension = ".gif";
bitmapEncoder = new GifBitmapEncoder();
break;
default:
fileExtension = ".jpg";
bitmapEncoder = new JpegBitmapEncoder();
break;
}
double imageQualityRatio = 1.0;
switch (this.OutputQuality)
{
case OutputQuality.Low:
imageQualityRatio /= 2.0;
break;
case OutputQuality.Good:
imageQualityRatio *= 2.0;
break;
case OutputQuality.Super:
imageQualityRatio *= 3.0;
break;
default:
imageQualityRatio *= 1.0;
break;
}
DocumentPage documentPage =
documentPageSequence.DocumentPaginator.GetPage(0);
RenderTargetBitmap targetBitmap = new RenderTargetBitmap(
(int)(documentPage.Size.Width * imageQualityRatio),
(int)(documentPage.Size.Height * imageQualityRatio),
96.0 * imageQualityRatio, 96.0 * imageQualityRatio,
PixelFormats.Pbgra32);
targetBitmap.Render(documentPage.Visual);
bitmapEncoder.Frames.Add(BitmapFrame.Create(targetBitmap));
string str4 = string.Format("{0}{1}",
fileNameWithoutExtension, fileExtension);
MemoryStream memoryStream = new MemoryStream();
bitmapEncoder.Save(memoryStream);
this.OutputStream = memoryStream;
xpsDocument.Close();
}
}
Using the Code
The class itself is a very simple class and is made for simplicity. Below is a small snippet of how to utilize the class:
converter.XpsFileName = "XPSdocument.xps";
converter.OutputFormat = OutputFormat.Png;
converter.OutputQuality = OutputQuality.Super;
converter.GenerateThumbnail();
Conclusion
The sample application provided with this article demonstrates the utilization of the code. In the demo application, you need to save the image by invoking a context menu from the thumbnail to see the output as I'm using an in-memory image stream to display the image on the picture box.
And, please don't hesitate to provide feedback, good or bad! I hope you enjoyed this article.
My name is Pravesh Soni and I’m software professional. I got involved with computers since last two decades starting with playing games developed in BASIC. I am a tech enthusiast and I love writing code, blogging, science fiction, cartoons, music, robotics and I am a big Microsoft fan too.
I started programming in classic asp but later switch to .net and now at present I have almost 15 years of development experience in Microsoft technologies. I got involved in customized software development in my career of programming, now contributing to some open source community development.