Click here to Skip to main content
Click here to Skip to main content
Articles » Multimedia » GDI+ » General » Downloads
 
Add your own
alternative version

Generate Thumbnail Images from PDF Documents

, 11 May 2004
This article presents VB.NET code to create thumbnail images from a directory of Adobe Acrobat PDF documents using the .NET Framework.
pdfthumbnailcsharp_src.zip
C#
01-Welcome.pdf
01-Welcome.png
20-QualityLandscape.pdf
20-QualityLandscape.png
PDFThumbnailCsharp
App.ico
bin
Release
Interop.Acrobat.dll
pdftemplate_landscape.gif
pdftemplate_portrait.gif
PDFThumbnailCsharp.exe
pdftemplate_landscape.gif
pdftemplate_portrait.gif
PDFThumbnailCsharp.csproj.user
pdfthumbnail_src.zip
Thumbnails
01-Welcome.pdf
01-Welcome.png
20-QualityLandscape.pdf
20-QualityLandscape.png
PDFThumbnail
bin
Interop.Acrobat.dll
pdftemplate_landscape.gif
pdftemplate_portrait.gif
PDFThumbnail.exe
pdftemplate_landscape.gif
pdftemplate_portrait.gif
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

Share

About the Author

Jonathan Hodgson
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/

| Advertise | Privacy | Terms of Use | Mobile
Web03 | 2.8.150128.1 | Last Updated 12 May 2004
Article Copyright 2004 by Jonathan Hodgson
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid