PDFtoolkit VCL
Edit, enhance, secure, merge, split, view, print PDF and AcroForms documents
Compatibility
Delphi C++Builder

Convert PDF Documents to Multipage TIFF Images In Delphi

Learn to export PDF pages using PDFtoolkit VCL and create multi-page TIFFs using Windows GDI.
V. Subhash
Important

With the release of Version 4 of PDFtoolkit, PDF-to-image conversion is much more simpler. It takes a single method call - TgtPDFDocument.SaveAsImage(). A special article titled "PDF-to-Image Export Using PDFtoolkit V4" has been written for users of Version 4. This article has been left here for users of older versions of PDFtoolkit.

PDFtoolkit offers several methods to export PDF pages. You could render to a canvas or to a stream. You can then repurpose the content ways not built into PDFtoolkit. In this article, we will see how to use GDIPlus library to create multi-page TIFF images.

Here are the steps:

  1. Use PDFtoolkit to render each page to a stream.
  2. Use Windows GDI to
    1. convert the stream to a single-page TIFF, and
    2. merge sigle-page TIFFs to a multi-page TIFF.

You can use Henri Gourvest's GDIPlus library or Erik Bilsen's Delphi 2009 GDIPLus Library.

Multi-Page TIFF Export Using Gourvest's GDIPLus Library

Now, here is the code listing. The GDI library names have been renamed to prevent conflicts with your existing libraries. You can find the full project in this zip file.

program Convert_PDF_to_TIFF;

{$APPTYPE CONSOLE}

uses
  SysUtils, Classes,
  gteGDIPAPI, gteGDIPOBJ, gteGDIPUTIL, ActiveX, TypInfo,
  gtPDFDoc, gtCstPDFDoc, Windows;
var
    gtPDFDocument1: TgtPDFDocument;
    PageWidth, PageHeight: Double;

    EMFStream: TMemoryStream;
    StreamAdapter: TStreamAdapter;

    MasterTIFF, TempTiff, AdditionalFrameTiff: TGPImage;

    EncoderParameters: TEncoderParameters;
    EncoderParameterValue: TEncoderValue;

    clsidTIFF: TGUID;
    Stat: TStatus;
    i, n: Integer;
begin
  // Initialize TEncoderParameters instance for
  // saving rendered PDF page content stream to TIFF
  EncoderParameters.Count := 1;
  EncoderParameters.Parameter[0].Guid := EncoderSaveFlag;
  EncoderParameters.Parameter[0].Type_ := EncoderParameterValueTypeLong;
  EncoderParameters.Parameter[0].NumberOfValues := 1;
  EncoderParameters.Parameter[0].Value := @EncoderParameterValue;
  GetEncoderClsid('image/tiff', clsidTIFF);

  // Create a document object
  gtPDFDocument1 := TgtPDFDocument.Create(nil);

  try
    Writeln('Loading sample_doc.pdf...');
    // Load a PDF document
    gtPDFDocument1.LoadFromFile('sample_doc.pdf');
    // Check if document was loaded successfully
    if gtPDFDocument1.IsLoaded then begin
      // Iterate through all the pages of the document
      n := gtPDFDocument1.PageCount;
      for i := 1 to n do begin
        // Obtain current page dimensions
        PageWidth := gtPDFDocument1.GetPageSize(1, muPixels).Width;
        PageHeight := gtPDFDocument1.GetPageSize(1, muPixels).Height;

        try
          EMFStream := TMemoryStream.Create;
          Write('Rendering page #' + IntToStr(i));
          // Export current page to a stream
          gtPDFDocument1.RenderToStream(
                  EMFStream,  // Memory stream
                  i,          // Page number
                  PageWidth,  // Page width
                  PageHeight, // Page height
                  96,         // X-axis DPI
                  96);        // Y-axis DPI

          // Save EMF stream to a temporary TIFF file
          EMFStream.Position := 0;
          StreamAdapter := TStreamAdapter.Create(EMFStream);
          TempTiff := TGPImage.Create(StreamAdapter);
          TempTiff.Save('temp' + IntToStr(i) + '.tiff', clsidTIFF);
          TempTiff.Free;
          EMFStream.Clear;

          // Add current TIFF file to a multipage TIFF
          if i = 1 then begin           // for the first frame
            MasterTIFF := TGPImage.Create('temp' + IntToStr(i) + '.tiff');
            EncoderParameterValue := EncoderValueMultiFrame;
            Stat := MasterTIFF.Save('multipage.tiff', clsidTIFF, @EncoderParameters);
          end else begin                // for additional frames
            AdditionalFrameTiff := TGPImage.Create('temp' + IntToStr(i) + '.tiff');
            EncoderParameterValue := EncoderValueFrameDimensionPage;
            Stat := MasterTIFF.SaveAdd(AdditionalFrameTiff, @EncoderParameters);
            AdditionalFrameTiff.Free;
          end;

          if Stat = Ok then begin
            Writeln('... Success!');
          end else begin
            Writeln('... Failed! ' + GetEnumName(TypeInfo(TStatus), Integer(Stat)));
          end;

        except on Err1:Exception do begin
            Writeln('Sorry, an exception was raised:');
            Writeln(Err1.Classname + ':' + Err1.Message + #10 + #13);
          end;
        end;
      end;

      // Save the multipage TIFF file
      EncoderParameterValue := EncoderValueFlush;
      MasterTIFF.SaveAdd(@EncoderParameters);
      MasterTIFF.Free;

      // Clean up temp files
      for i := 1 to n do begin
        DeleteFile(PWideChar('temp' + IntToStr(i) + '.tiff'));
      end;

      Writeln('Check multipage.tiff.');
    end else begin
      Writeln('Sorry, I could not load sample_doc.pdf.');
    end;
  except
    on Err2:Exception do begin
        Writeln('Sorry, an exception was raised. ');
        Writeln(Err2.Classname + ': ' + Err2.Message);
    end;
  end;

  // Close PDF document
  gtPDFDocument1.Reset;
  FreeAndNil(gtPDFDocument1);

  Writeln('Press Enter to exit.');
  Readln;
end.

Multi-Page TIFF Export Using Bilsen's GDI+ Library

Bilsen's GDI+ library is recommened only for user with Delphi 2009 or above. You can find the GDI library and full project source code in this zip file.

program Convert_PDF_to_TIFF;

{$APPTYPE CONSOLE}

uses
  SysUtils, Classes, GdiPlus, GdiPlusHelpers,
  TypInfo, gtPDFDoc, gtCstPDFDoc, Windows;
var
    gtPDFDocument1: TgtPDFDocument;
    PageWidth, PageHeight: Double;
    EMFStream: TMemoryStream;
    StreamAdapter: TStreamAdapter;

    MasterTIFF, TempTIFF, AdditionalFrameTiff: IGPImage;

    Codec: IGPImageCodecInfo;
    EncoderParameters: IGPEncoderParameters;

    i, n: Integer;
    HaveTiffEncoder: boolean;
begin

  HaveTiffEncoder := False;
  // Find the TIFF encoder
  for Codec in TGPImageCodecInfo.GetImageEncoders do begin
    if SameText(Codec.MimeType, 'image/tiff') then begin
      HaveTiffEncoder := true;
      Break;
    end;
  end;

  // Exit if no TIFF encoder is found
  if not HaveTiffEncoder then begin
    Writeln('Sorry. TIFF encoder is not available!');
    Exit;
  end;

  // Create a PDF document object
  gtPDFDocument1 := TgtPDFDocument.Create(nil);

  try
    Writeln('Loading sample_doc.pdf...');
    // Load a PDF document
    gtPDFDocument1.LoadFromFile('sample_doc.pdf');

    // Check if document was loaded successfully
    if gtPDFDocument1.IsLoaded then begin
      // Iterate through all the pages of the document
      n := gtPDFDocument1.PageCount;

      for i := 1 to n do begin
        // Obtain current page dimensions
        PageWidth := gtPDFDocument1.GetPageSize(1, muPixels).Width;
        PageHeight := gtPDFDocument1.GetPageSize(1, muPixels).Height;

        try
          // Export current page contents to a stream
          EMFStream := TMemoryStream.Create;
          Writeln('Exporting page #' + IntToStr(i) + ' from the PDF...');
          gtPDFDocument1.RenderToStream(
                  EMFStream,  // Memory stream
                  i,          // Page number
                  PageWidth,  // Page width
                  PageHeight, // Page height
                  96,         // X-axis DPI
                  96);        // Y-axis DPI

          // Save the EMF stream to a temporary TIFF file
          EMFStream.Position := 0;
          StreamAdapter := TStreamAdapter.Create(EMFStream);
          TempTIFF := TGPImage.Create(StreamAdapter);
          TempTIFF.Save('temp' + IntToStr(i) + '.tiff',  // file name
                        TGPImageFormat.Tiff);            // format
          TempTIFF := Nil;
          StreamAdapter := Nil;
          EMFStream.Free;

          // Add current TIFF file to a multipage TIFF
          EncoderParameters := TGPEncoderParameters.Create;
          Writeln('Saving page #' + IntToStr(i) + ' to TIFF...');
          if i = 1 then begin       // for the first frame
            EncoderParameters.Add(EncoderSaveFlag, EncoderValueMultiFrame);
            MasterTIFF := TGPImage.Create('temp1.tiff');
            MasterTIFF.Save('multipage.tiff', TGPImageFormat.Tiff, EncoderParameters);
          end else begin            // for other frames
            AdditionalFrameTiff := TGPImage.Create('temp' + IntToStr(i) + '.tiff');
            EncoderParameters.Add(EncoderSaveFlag, EncoderValueFrameDimensionPage);
            MasterTIFF.SaveAdd(AdditionalFrameTiff, EncoderParameters);
            AdditionalFrameTiff := Nil;
          end;
          EncoderParameters.Clear;

         except on Err1:Exception do begin
            Writeln('Sorry, an exception was raised:');
            Writeln(Err1.Classname + ':' + Err1.Message + #10 + #13);
          end;
        end;
      end;

      // Save the multipage TIFF image to file
      EncoderParameters.Clear;
      EncoderParameters.Add(EncoderSaveFlag, EncoderValueFlush);
      MasterTIFF.SaveAdd(EncoderParameters);
      MasterTIFF := Nil;
      Writeln('Check multipage.tiff.');

      // Clean up the temporary TIFF files
      for i := 1 to n do begin
        DeleteFile(PWideChar('temp' + IntToStr(i) + '.tiff'));
      end;

    end else begin
      Writeln('Sorry, I could not load sample_doc.pdf.');
    end;
  except
    on Err2:Exception do begin
        Writeln('Sorry, an exception was raised. ');
        Writeln(Err2.Classname + ': ' + Err2.Message);
    end;
  end;

  // Close PDF document
  gtPDFDocument1.Reset;
  FreeAndNil(gtPDFDocument1);

  Writeln('Press Enter to exit.');
  Readln;
end.

Thanks

Gnostice wishes to thank Erik Bilsen for the help he rendered while writing the second part of the article.

---o0O0o---

Our Free Online Document-Processing Tools
Gnostice Apps

Gnostice Apps provides several PDF document-processing services over the Web. It enables you to merge, split, convert, secure and redact PDF documents - all for FREE. All you need to access these services is a HTML5-capable browser such as the latest version of Firefox/Seamonkey or IE 11.

Our Developer Tools
eDocEngine VCL

A Delphi/C++Builder component suite for creating documents in over 20 formats and also export reports from popular Delphi reporting tools.

PDFtoolkit VCL

A Delphi/C++Builder component suite to edit, enhance, view, print, merge, split, encrypt, annotate, and bookmark PDF documents.

XtremePDFConverter VCL

A Delphi/C++Builder component to intelligently convert PDF to user-friendly Word RTF documents.

PDFOne .NET

A .NET PDF component suite to create, edit, view, print, reorganize, encrypt, annotate, and bookmark PDF documents in .NET applications.

XtremeDocumentStudio .NET

Multi-format document-processing component suite for .NET developers

PDFOne (for Java™)

A Java™ PDF component suite to create, edit, view, print, reorganize, encrypt, annotate, bookmark PDF documents in Java™ applications.

XtremeFontEngine (for Java)

Java font engine to render glyphs from Type 1, Type 2 (CFF), and TrueType fonts

Our Office Productivity Applications
Free PDF Reader

A free, fast, and portable application for viewing, printing and converting PDF documents.

Privacy | Legal | Feedback | Newsletter | Resellers © 2002-2014 Gnostice Information Technologies Private Limited. All rights reserved.

This site is best viewed on a screen with minimum resolution of 1152 x 864 pixels. Windows XP users are advised to use Microsoft ClearType Tuning for optimal experience. Also, please use the latest version of a standards-compliant browser such as Firefox, Opera, or Dragon (Chromium).