Click here to Skip to main content
15,879,096 members
Articles / Web Development / ASP.NET

Generate Thumbnail Images from PDF Documents

Rate me:
Please Sign up or sign in to vote.
4.90/5 (111 votes)
11 May 200410 min read 983.9K   28.3K   300  
This article presents VB.NET code to create thumbnail images from a directory of Adobe Acrobat PDF documents using the .NET Framework.
using System;
using System.IO;
using System.Drawing;
using System.Configuration;
using System.Windows.Forms;
using System.Runtime.InteropServices;

class PDFThumbnailCsharp
{
	[STAThread]
	static void Main(string[] args)
	{
		// Acrobat objects
		Acrobat.CAcroPDDoc pdfDoc;
		Acrobat.CAcroPDPage pdfPage;
		Acrobat.CAcroRect pdfRect;
		Acrobat.CAcroPoint pdfPoint;

		AppSettingsReader appSettings = new AppSettingsReader();

		string pdfInputPath = appSettings.GetValue("pdfInputPath", typeof(string)).ToString();
		string pngOutputPath = appSettings.GetValue("pngOutputPath", typeof(string)).ToString();

        string templatePortraitFile = Application.StartupPath + @"\pdftemplate_portrait.gif";
		string templateLandscapeFile = Application.StartupPath + @"\pdftemplate_portrait.gif";;

		try
		{
			// Get list of files to process from the input path
            // Could change to read list from database instead
			string[] files = Directory.GetFiles(pdfInputPath, "*.pdf");

			for (int n=0; n < files.Length; n++)
			{
				string inputFile = files[n].ToString();
				string outputFile = pngOutputPath + files[n].Substring(files[n].LastIndexOf(@"\")+1).Replace(".pdf", ".png");

                /* Could skip if thumbnail already exists in output path
                FileInfo fi = new FileInfo(inputFile);
				if (!fi.Exists) {} */

				// Create the document (Can only create the AcroExch.PDDoc object using late-binding)
				// Note using VisualBasic helper functions, have to add reference to DLL in
				// C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\Microsoft.VisualBasic.dll
				// Will always be available as .NET framework ships with all
				pdfDoc = (Acrobat.CAcroPDDoc) Microsoft.VisualBasic.Interaction.CreateObject("AcroExch.PDDoc", "");

				int ret = pdfDoc.Open(inputFile);

				if (ret == 0)
				{
					throw new FileNotFoundException();
				}

				// Get the number of pages (to be used later if you wanted to store that information)
				int pageCount = pdfDoc.GetNumPages();

				// Get the first page
				pdfPage = (Acrobat.CAcroPDPage)pdfDoc.AcquirePage(0);

				pdfPoint = (Acrobat.CAcroPoint)pdfPage.GetSize();
				
				pdfRect = (Acrobat.CAcroRect) Microsoft.VisualBasic.Interaction.CreateObject("AcroExch.Rect", "");

				pdfRect.Left = 0;
				pdfRect.right = pdfPoint.x;
				pdfRect.Top = 0;
				pdfRect.bottom = pdfPoint.y;

				// Render to clipboard, scaled by 100 percent (ie. original size)
                // Even though we want a smaller image, better for us to scale in .NET
                // than Acrobat as it would greek out small text
                // see http://www.adobe.com/support/techdocs/1dd72.htm
				pdfPage.CopyToClipboard(pdfRect, 0, 0, 100);

				IDataObject clipboardData = Clipboard.GetDataObject();

				if (clipboardData.GetDataPresent(DataFormats.Bitmap))
				{
					Bitmap pdfBitmap = (Bitmap)clipboardData.GetData(DataFormats.Bitmap);

					// Size of generated thumbnail in pixels
					int thumbnailWidth = 45;
					int thumbnailHeight = 59;

					string templateFile;

					// Switch between portrait and landscape
					if (pdfPoint.x < pdfPoint.y)
					{
						templateFile = templatePortraitFile;
					}
					else
					{
						templateFile = templateLandscapeFile;
						// Swap width and height (little trick not using third temp variable)
						thumbnailWidth = thumbnailWidth ^ thumbnailHeight;
						thumbnailHeight = thumbnailWidth ^ thumbnailHeight;
						thumbnailWidth = thumbnailWidth ^ thumbnailHeight;
					}
					
					// Load the template graphic
					Bitmap templateBitmap = new Bitmap(templateFile);

					// Render to small image using the bitmap class
					Image pdfImage = pdfBitmap.GetThumbnailImage(thumbnailWidth, thumbnailHeight,
																 null, IntPtr.Zero);
					
					// Create new blank bitmap (+ 7 for template border)						 
					Bitmap thumbnailBitmap = new Bitmap(thumbnailWidth + 7, thumbnailHeight + 7,
														System.Drawing.Imaging.PixelFormat.Format32bppArgb);

					// To overlayout the template with the image, we need to set the transparency
                    // http://www.sellsbrothers.com/writing/default.aspx?content=dotnetimagerecoloring.htm
					templateBitmap.MakeTransparent();

					using (Graphics thumbnailGraphics = Graphics.FromImage(thumbnailBitmap))
					{
						// Draw rendered pdf image to new blank bitmap
						thumbnailGraphics.DrawImage(pdfImage, 2, 2, thumbnailWidth, thumbnailHeight);

						// Draw template outline over the bitmap (pdf with show through the transparent area)
						thumbnailGraphics.DrawImage(templateBitmap, 0, 0);

						// Save as .png file
						thumbnailBitmap.Save(outputFile, System.Drawing.Imaging.ImageFormat.Png);

						Console.WriteLine("Generated thumbnail... {0}", outputFile);
					}

					pdfDoc.Close();

					// Not sure how why it is to do this, but Acrobat is not the best behaved COM object
					// see http://blogs.msdn.com/yvesdolc/archive/2004/04/17/115379.aspx
					Marshal.ReleaseComObject(pdfPage);
					Marshal.ReleaseComObject(pdfRect);
					Marshal.ReleaseComObject(pdfDoc);
				}
			}
		}
		catch (System.Exception ex)
		{
			Console.Write(ex.ToString());
		}
		
	}
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer
United Kingdom United Kingdom
Jonathan Hodgson works as Software Developer in London, UK.

He started programming in the '80s on a trusty 48k Spectrum before moving to PC development in the early 90s. During the working week most of his time is spent involved in application development both Windows and Web-based; .NET, C#, ASP.NET, SQL Server.

He is a Microsoft Certified Software Developer (MCSD) and MCP for developing web applications using ASP.NET in C# and is always looking for new projects and challenges to work on.

http://www.jonathanhodgson.co.uk/

Comments and Discussions