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
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.