{ simple example showing how to scan to a multi page PDF file }
unit ScanUnit;

interface

uses
  EnScan,    { for TScanner }
  EnTifGr,   { for TTiffGraphic }

  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls;

type

TScanInfo = record
    TifFileName : String;
    TifGraphic  : TTiffGraphic;
    PageCount   : Integer;
end;

type
  TScanToPDFForm = class(TForm)
    SelectScannerBtn: TButton;
    ScanToPDFBtn: TButton;
    procedure FormCreate(Sender: TObject);
    procedure SelectScannerBtnClick(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure ScanToPDFBtnClick(Sender: TObject);
  private
    { Private declarations }
    FScanner        : TScanner;
    FScanInfo       : TScanInfo;

    { event handler to receive page from scanner }
    procedure AcquirePage( const DibHandle    : THandle;
                           const XDpi         : Word;
                           const YDpi         : Word;
                           const CallBackData : Pointer );

    { call back method for TPdfGraphic.MultiSaveToStream }
    function GetPageFromTempTifFile( const ImageNo     : Integer;
                                     var   FreeGraphic : Boolean ) : TGraphic;




  public
    { Public declarations }
  end;

var
  ScanToPDFForm: TScanToPDFForm;

implementation

uses
    EnPdfGr,  { for TPdfGraphic }
    EnMisc;   { for GetTempFileName }

{$R *.dfm}


procedure TScanToPDFForm.FormCreate(Sender: TObject);
begin
    FScanner               := TScanner.Create;
end;

{--------------------------------------------------------------------------}

procedure TScanToPDFForm.FormDestroy(Sender: TObject);
begin
    FScanner.Free;
end;

{--------------------------------------------------------------------------}

procedure TScanToPDFForm.ScanToPDFBtnClick(Sender: TObject);
var
    SaveDialog       : TSaveDialog;
    PdfFileName      : String;
    PdfGraphic       : TPdfGraphic;

begin
    { for first Scan to a multi page tiff file and then TPdfGraphic MultiSaveToFile
      will be used as it is much more efficient to create a multi page PDF }

    SaveDialog := TSaveDialog.Create(nil);
    try
        SaveDialog.Filter := GraphicFilter(TPdfGraphic);
        if SaveDialog.Execute then
        begin
            PdfFileName := SaveDialog.FileName;

            if ExtractFileExt(PdfFileName) = '' then
                PdfFileName := ChangeFileExt( PdfFileName, '.pdf' );

            if FileExists(PdfFileName) and
               (MessageDlg( 'File ' + PdfFileName + ' exists.'#13 + ' Overwrite ?',
                             mtConfirmation, [mbYes, mbNo], 0) <> mrYes) then
                Abort;

        end;
    finally
        SaveDialog.Free;
    end;

    FScanInfo.TifFileName := EnMisc.GetTempFileName( 'Tmp', 'tif' );
    FScanInfo.TifGraphic  := TTiffGraphic.Create;
    FScanInfo.PageCount   := 0;
    PdfGraphic            := TPdfGraphic.Create;
    try
        FScanInfo.TifGraphic.Compression  := tcZLib;

        FScanner.Acquire( AcquirePage, nil );

        if FScanInfo.PageCount > 0 then
        begin
            PdfGraphic.MultiSaveToFile( PdfFileName, FScanInfo.PageCount, GetPageFromTempTifFile );
            MessageDlg( 'PDF file ' + PdfFilename + ' was created successfully', mtInformation, [mbOk], 0 );
        end;

    finally
        FScanInfo.TifGraphic.Free;
        DeleteFile( FScanInfo.TifFileName );
        PdfGraphic.Free;
    end;

end;

{--------------------------------------------------------------------------}

procedure TScanToPDFForm.SelectScannerBtnClick(Sender: TObject);
begin
    FScanner.SelectScanner;
end;

{--------------------------------------------------------------------------}

procedure TScanToPDFForm.AcquirePage(
                       const DibHandle    : THandle;
                       const XDpi         : Word;
                       const YDpi         : Word;
                       const CallBackData : Pointer );
begin
    FScanInfo.TifGraphic.AssignFromDibHandle(DibHandle);
    FScanInfo.TifGraphic.XDotsPerInch := XDpi;
    FScanInfo.TifGraphic.YDotsPerInch := YDpi;

    if FScanInfo.PageCount = 0 then
        FScanInfo.TifGraphic.SaveToFile(FScanInfo.TifFileName)
    else
        FScanInfo.TifGraphic.AppendToFile(FScanInfo.TifFileName);

    Inc(FScanInfo.PageCount);
end;

{--------------------------------------------------------------------------}

function TScanToPDFForm.GetPageFromTempTifFile(
                                     const ImageNo     : Integer;
                                     var   FreeGraphic : Boolean ) : TGraphic;
begin
    Result := TTiffGraphic.Create;
    TTiffGraphic(Result).ImageToLoad := ImageNo;
    Result.LoadFromFile( FScanInfo.TifFileName );

    FreeGraphic := True;
end;

{--------------------------------------------------------------------------}

end.
