Техническая статья

Преобразование изображений в PDF-документы с помощью PDFium VCL в Delphi

Преобразование изображений в PDF является распространенной необходимостью для управления документами, архивирования и обмена. Демонстрация "Image to PDF" Демонстрация показывает, как создавать многостраничные PDF-документы из набора изображений с использованием PDFium VCL.

Обзор

Эта демонстрация позволяет пользователям выбирать несколько изображений, просматривать их, при необходимости изменять порядок и преобразовывать их в один PDF-документ. Каждое изображение становится страницей в PDF-файле, правильно масштабированным и центрированным.

Основные функции

  • Поддержка нескольких изображений – Добавляйте несколько изображений одновременно.
  • Поддерживаемые форматы – JPEG, PNG, BMP, GIF и TIFF.
  • Предварительный просмотр изображения. Предварительный просмотр изображений перед преобразованием.
  • Автоматическое определение размера страницы. Ориентация страницы: портретная или альбомная, в зависимости от ориентации изображения.
  • Интеллектуальное масштабирование. Изображения масштабируются для соответствия размеру страницы с отступами.
  • Информация об изображении. Отображение исходного размера и коэффициента масштабирования на каждой странице.

Требования к библиотеке PDFium DLL

Перед запуском любого приложения PDFium VCL, убедитесь, что файлы PDFium DLL установлены:

  • pdfium32.dll / pdfium64.dll – Стандартные версии (около 5-6 МБ)
  • pdfium32v8.dll / pdfium64v8.dll – С JavaScript-движком V8 (около 23-27 МБ)

Установка: Запуск PDFiumVCL\DLLs\CopyDlls.bat от имени администратора для автоматической копии DLL-файлов в системные каталоги Windows.

Создание PDF-файлов из изображений.

Основной процесс преобразования:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
procedure TFormMain.CreatePDFFromImages;
var
  I: Integer;
  PageWidth, PageHeight: Double;
  ImageWidth, ImageHeight: Double;
  ScaleX, ScaleY, Scale: Double;
  ImageSize: TSize;
  X, Y: Double;
  Picture: TPicture;
begin
  if FImageList.Count = 0 then
    Exit;
    
  ProgressBar.Visible := True;
  ProgressBar.Max := FImageList.Count;
  ProgressBar.Position := 0;
  
  try
    // Create new PDF document
    Pdf.CreateDocument;
    Pdf.Active := True;
    
    for I := 0 to FImageList.Count - 1 do
    begin
      try
        // Load the image
        Picture := TPicture.Create;
        try
          Picture.LoadFromFile(FImageList[I]);
          
          // Get image dimensions
          ImageSize.cx := Picture.Width;
          ImageSize.cy := Picture.Height;
          
          // Set page orientation based on image
          if ImageSize.cx > ImageSize.cy then
          begin
            // Landscape
            PageWidth := 842;  // A4 landscape
            PageHeight := 595;
          end
          else
          begin
            // Portrait
            PageWidth := 595;  // A4 portrait
            PageHeight := 842;
          end;
          
          // Create page
          Pdf.AddPage(I + 1, PageWidth, PageHeight);
          Pdf.PageNumber := I + 1;
          
          // Calculate scaling
          ImageWidth := ImageSize.cx;
          ImageHeight := ImageSize.cy;
          
          ScaleX := (PageWidth - 80) / ImageWidth;   // 40pt margin each side
          ScaleY := (PageHeight - 120) / ImageHeight; // 40pt + space for text
          Scale := Min(ScaleX, ScaleY);
          
          ImageWidth := ImageWidth * Scale;
          ImageHeight := ImageHeight * Scale;
          
          // Center on page
          X := (PageWidth - ImageWidth) / 2;
          Y := (PageHeight - ImageHeight) / 2;
          
          // Add image to PDF
          Pdf.AddPicture(Picture, X, Y, ImageWidth, ImageHeight);
          
          // Add image information
          Pdf.AddText(Format('File: %s', [ExtractFileName(FImageList[I])]),
            'Arial', 10, X, Y + ImageHeight + 10, clBlack, $FF, 0.0);
          Pdf.AddText(Format('Original: %dx%d px, Scale: %.1f%%',
            [ImageSize.cx, ImageSize.cy, Scale * 100]),
            'Arial', 8, X, Y + ImageHeight + 25, clGray, $FF, 0.0);
            
        finally
          Picture.Free;
        end;
        
        ProgressBar.Position := I + 1;
        Application.ProcessMessages;
        
      except
        on E: Exception do
          // Continue with next image on error
          LabelStatus.Caption := 'Error: ' + E.Message;
      end;
    end;
    
    // Save the PDF
    Pdf.SaveAs(SaveDialog.FileName);
    ShowMessage(Format('PDF created with %d pages!', [FImageList.Count]));
    
  finally
    ProgressBar.Visible := False;
    Pdf.Active := False;
  end;
end;

Добавление изображений в список.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
procedure TFormMain.BtnAddImagesClick(Sender: TObject);
var
  I: Integer;
  ListItem: TListItem;
  FileSize: Int64;
  FileSizeStr: string;
begin
  if OpenPictureDialog.Execute then
  begin
    for I := 0 to OpenPictureDialog.Files.Count - 1 do
    begin
      FImageList.Add(OpenPictureDialog.Files[I]);
      
      // Add to ListView
      ListItem := ListView.Items.Add;
      ListItem.Caption := ExtractFileName(OpenPictureDialog.Files[I]);
      ListItem.SubItems.Add(OpenPictureDialog.Files[I]); // Full path
      
      // Get file size
      try
        FileSize := GetFileSizeHelper(OpenPictureDialog.Files[I]);
        if FileSize >= 1024 * 1024 then
          FileSizeStr := Format('%.1f MB', [FileSize / (1024 * 1024)])
        else if FileSize >= 1024 then
          FileSizeStr := Format('%.1f KB', [FileSize / 1024])
        else
          FileSizeStr := Format('%d bytes', [FileSize]);
      except
        FileSizeStr := 'Unknown';
      end;
      ListItem.SubItems.Add(FileSizeStr);
    end;
    
    UpdateUI;
    LabelStatus.Caption := Format('Added %d image(s). Total: %d images',
      [OpenPictureDialog.Files.Count, FImageList.Count]);
  end;
end;

Использование метода AddPicture.

The AddPicture метод принимает объект, который поддерживает различные форматы изображений: TPicture объект, который поддерживает различные форматы изображений:

1
2
3
4
5
// Add picture with automatic sizing
procedure TPdf.AddPicture(Picture: TPicture; X, Y: Double);
 
// Add picture with specific size
procedure TPdf.AddPicture(Picture: TPicture; X, Y, Width, Height: Double);

Добавление изображений JPEG напрямую.

Для изображений JPEG можно использовать оптимизированный. AddJpegImage метод:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
function AddJpegFromFile(const FileName: string): Boolean;
var
  Pdf: TPdf;
  FileStream: TFileStream;
begin
  Pdf := TPdf.Create(nil);
  try
    Pdf.CreateDocument;
    Pdf.Active := True;
    Pdf.AddPage(1, 595, 842);
    Pdf.PageNumber := 1;
    
    FileStream := TFileStream.Create(FileName, fmOpenRead);
    try
      // Add JPEG directly - more efficient than loading as TPicture
      Result := Pdf.AddJpegImage(FileStream, 50, 50, 495, 742);
    finally
      FileStream.Free;
    end;
    
    Pdf.SaveAs('output.pdf');
    
  finally
    Pdf.Active := False;
    Pdf.Free;
  end;
end;

Предварительный просмотр выбранных изображений.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
procedure TFormMain.ListViewSelectItem(Sender: TObject; Item: TListItem;
  Selected: Boolean);
begin
  if Selected and (Item <> nil) then
  begin
    LoadImagePreview(Item.SubItems[0]); // Full path
  end;
end;
 
procedure TFormMain.LoadImagePreview(const FileName: string);
begin
  try
    if FileExists(FileName) then
    begin
      ImagePreview.Picture.LoadFromFile(FileName);
      ImagePreview.Proportional := True;
      ImagePreview.Stretch := True;
      LabelStatus.Caption := 'Preview: ' + ExtractFileName(FileName);
    end;
  except
    on E: Exception do
    begin
      ImagePreview.Picture.Assign(nil);
      LabelStatus.Caption := 'Error loading preview: ' + E.Message;
    end;
  end;
end;

Удаление и переупорядочивание изображений.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
procedure TFormMain.BtnRemoveSelectedClick(Sender: TObject);
var
  I, RemovedCount: Integer;
begin
  RemovedCount := 0;
  
  if ListView.SelCount > 0 then
  begin
    // Remove from back to front to avoid index issues
    for I := ListView.Items.Count - 1 downto 0 do
    begin
      if ListView.Items[I].Selected then
      begin
        FImageList.Delete(I);
        ListView.Items.Delete(I);
        Inc(RemovedCount);
      end;
    end;
    
    if (FImageList.Count = 0) or (ListView.Selected = nil) then
      ImagePreview.Picture.Assign(nil);
      
    UpdateUI;
    LabelStatus.Caption := Format('Removed %d item(s). Total: %d images',
      [RemovedCount, FImageList.Count]);
  end;
end;

Настройка диалогового окна.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
procedure TFormMain.FormCreate(Sender: TObject);
begin
  FImageList := TStringList.Create;
  
  // Setup ListView
  ListView.ViewStyle := vsReport;
  ListView.Columns.Add.Caption := 'File Name';
  ListView.Columns.Add.Caption := 'Path';
  ListView.Columns.Add.Caption := 'Size';
  ListView.Columns[0].Width := 200;
  ListView.Columns[1].Width := 300;
  ListView.Columns[2].Width := 100;
  ListView.RowSelect := True;
  ListView.MultiSelect := True;
  
  // Setup dialogs
  OpenPictureDialog.Filter :=
    'Image Files|*.jpg;*.jpeg;*.png;*.bmp;*.gif;*.tiff;*.tif|' +
    'JPEG Files|*.jpg;*.jpeg|' +
    'PNG Files|*.png|' +
    'Bitmap Files|*.bmp|' +
    'All Files|*.*';
  OpenPictureDialog.Options := [ofAllowMultiSelect, ofPathMustExist, ofFileMustExist];
  
  SaveDialog.Filter := 'PDF Files|*.pdf|All Files|*.*';
  SaveDialog.DefaultExt := 'pdf';
  
  UpdateUI;
end;

Примеры использования.

  • Фотоальбомы. – Создание PDF-альбомов из цифровых фотографий.
  • Сканирование документов. – Объединение отсканированных изображений страниц в один PDF-файл.
  • Создание портфолио. – Создание PDF-портфолио из изображений.
  • Архивирование. – Преобразование коллекций изображений в PDF-файлы для долгосрочного хранения.
  • Генерация отчетов. – Включение скриншотов и диаграмм в PDF-отчеты.

Заключение.

Демонстрация Image to PDF показывает, как PDFium VCL позволяет легко создавать профессиональные PDF-документы из изображений. Благодаря автоматической настройке размера страницы, интеллектуальному масштабированию и поддержке различных форматов изображений, вы можете создавать мощные инструменты для преобразования изображений в PDF.

The AddPicture Этот метод обрабатывает сложность встраивания изображений в страницы PDF, позволяя вам сосредоточиться на пользовательском интерфейсе и рабочих процессах вашего приложения.

Попробуйте компонент PDFium VCL. Зайдите на loslab.com и начните создавать PDF-файлы из изображений уже сегодня.