Artículo técnico

Extracción de imágenes de documentos PDF con PDFium VCL en Delphi

· Programación PDF

Los documentos PDF a menudo contienen imágenes valiosas: fotografías, diagramas, gráficos y elementos gráficos. Extraer imágenes La demostración muestra cómo extraer todas las imágenes incrustadas de un documento PDF utilizando PDFium VCL, guardándolas en formatos óptimos según sus características.

Resumen

Esta demostración extrae imágenes incrustadas (mapas de bits) de las páginas PDF y las guarda como archivos de imagen separados. Incluye una vista previa de la imagen, detección de formato y extracción por lotes con seguimiento del progreso.

Características principales

  • Extraer todas las imágenes – Extrae cada imagen incrustada del PDF.
  • Selección del rango de páginas – Extrae solo de páginas específicas.
  • Detección inteligente de formato. – Selecciona automáticamente JPEG, PNG o BMP según las características de la imagen.
  • Vista previa de la imagen. – Previsualiza las imágenes extraídas antes de guardarlas.
  • Información detallada. – Visualiza las dimensiones, el formato y el tamaño del archivo.
  • Procesamiento por lotes. – Extrae múltiples imágenes con seguimiento del progreso.

Requisitos de la DLL PDFium

Antes de ejecutar cualquier aplicación PDFium VCL, asegúrese de que los archivos DLL de PDFium estén instalados:

  • pdfium32.dll / pdfium64.dll – Versiones estándar (~5-6 MB)
  • pdfium32v8.dll / pdfium64v8.dll – Con el motor JavaScript V8 (~23-27 MB)

Instalación: Ejecutar PDFiumVCL\DLLs\CopyDlls.bat como administrador para copiar automáticamente los archivos DLL a los directorios del sistema de Windows.

Extracción básica de imágenes.

Acceda a las imágenes integradas a través de las propiedades: Bitmap y BitmapCount .

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
procedure ExtractImagesSimple;
var
  Pdf: TPdf;
  I, J: Integer;
  Bitmap: TBitmap;
begin
  Pdf := TPdf.Create(nil);
  try
    Pdf.FileName := 'document.pdf';
    Pdf.Active := True;
    
    // Loop through all pages
    for I := 1 to Pdf.PageCount do
    begin
      Pdf.PageNumber := I;
      
      // Loop through all images on this page
      for J := 0 to Pdf.BitmapCount - 1 do
      begin
        Bitmap := Pdf.Bitmap[J];
        try
          // Save as BMP
          Bitmap.SaveToFile(Format('Page%d_Image%d.bmp', [I, J + 1]));
        finally
          Bitmap.Free;
        end;
      end;
    end;
    
  finally
    Pdf.Active := False;
    Pdf.Free;
  end;
end;

Extracción completa con detección de formato.

La demostración implementa la selección inteligente de formato:

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
procedure TFormMain.ButtonExtractClick(Sender: TObject);
var
  I, J, StartPage, EndPage: Integer;
  Bitmap: TBitmap;
  FullFileName, DetectedFormat, ImageExtension: string;
  ImageInfo: TImageInfo;
begin
  FCancelled := False;
  FProcessedImages := 0;
  FTotalImages := 0;
  
  ClearExtractedImages;
  EnableControls(False);
  
  try
    Pdf.FileName := EditPdfFile.Text;
    Pdf.PageNumber := 0;
    Pdf.Active := True;
    
    ParsePageRange(EditPageRange.Text, StartPage, EndPage);
    if EndPage = -1 then
      EndPage := Pdf.PageCount;
      
    // Calculate total images for progress
    for I := StartPage to EndPage do
    begin
      Pdf.PageNumber := I;
      FTotalImages := FTotalImages + Pdf.BitmapCount;
    end;
    
    ProgressBar.Max := FTotalImages;
    
    // Extract images
    for I := StartPage to EndPage do
    begin
      if FCancelled then
        Break;
        
      Pdf.PageNumber := I;
      
      for J := 0 to Pdf.BitmapCount - 1 do
      begin
        if FCancelled then
          Break;
          
        Bitmap := Pdf.Bitmap[J];
        if Assigned(Bitmap) then
        begin
          try
            // Detect optimal format
            DetectedFormat := DetectImageFormat(Bitmap);
            ImageExtension := GetExtensionForFormat(DetectedFormat);
            
            FullFileName := Format('%s\Page%d_Image%d%s',
              [FCurrentOutputDir, I, J + 1, ImageExtension]);
              
            SaveBitmapInOptimalFormat(Bitmap, FullFileName);
            
            // Store image info for preview
            ImageInfo.FileName := FullFileName;
            ImageInfo.PageNumber := I;
            ImageInfo.ImageIndex := J + 1;
            ImageInfo.Width := Bitmap.Width;
            ImageInfo.Height := Bitmap.Height;
            ImageInfo.Format := DetectedFormat;
            ImageInfo.Bitmap := TBitmap.Create;
            ImageInfo.Bitmap.Assign(Bitmap);
            
            AddImageInfo(ImageInfo);
            
            Inc(FProcessedImages);
            ProgressBar.Position := FProcessedImages;
            
          finally
            Bitmap.Free;
          end;
        end;
      end;
    end;
    
    UpdateImageList;
    
  finally
    Pdf.Active := False;
    EnableControls(True);
  end;
end;

Detección inteligente de formato.

Elija el formato óptimo según las características de la imagen:

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
function TFormMain.DetectImageFormat(ABitmap: TBitmap): string;
begin
  // Check if image has transparency (alpha channel)
  if ABitmap.PixelFormat = pf32bit then
  begin
    // PNG for transparency support
    Result := 'PNG';
  end
  // Check if it's likely a photographic image
  else if (ABitmap.Width * ABitmap.Height > 100000) and
          (ABitmap.PixelFormat in [pf24bit, pf32bit]) then
  begin
    // Large, complex image - use JPEG for smaller file size
    Result := 'JPEG';
  end
  else
  begin
    // Small or simple image - preserve quality with BMP
    Result := 'BMP';
  end;
end;
 
function TFormMain.GetExtensionForFormat(const AFormat: string): string;
begin
  case UpperCase(AFormat)[1] of
    'J': Result := '.jpg';
    'P': Result := '.png';
    'B': Result := '.bmp';
  else
    Result := '.bmp';
  end;
end;

Guardar en formato óptimo.

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
procedure TFormMain.SaveBitmapInOptimalFormat(ABitmap: TBitmap;
  const AFileName: string);
var
  JpegImg: TJPEGImage;
  FileExt: string;
begin
  FileExt := UpperCase(ExtractFileExt(AFileName));
  
  if FileExt = '.JPG' then
  begin
    // Save as JPEG with good quality
    JpegImg := TJPEGImage.Create;
    try
      JpegImg.Assign(ABitmap);
      JpegImg.CompressionQuality := 85; // Good quality/size balance
      JpegImg.SaveToFile(AFileName);
    finally
      JpegImg.Free;
    end;
  end
  else if FileExt = '.PNG' then
  begin
    // PNG would require additional library
    // Fall back to BMP for compatibility
    ABitmap.SaveToFile(ChangeFileExt(AFileName, '.bmp'));
  end
  else
  begin
    // BMP - lossless quality
    ABitmap.SaveToFile(AFileName);
  end;
end;

Usando TPdfImage para datos de imagen sin procesar.

Para casos de uso avanzados, acceda a los datos de imagen sin procesar:

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
procedure ProcessRawImageData;
var
  Pdf: TPdf;
  I: Integer;
  PdfImage: TPdfImage;
begin
  Pdf := TPdf.Create(nil);
  try
    Pdf.FileName := 'document.pdf';
    Pdf.Active := True;
    Pdf.PageNumber := 1;
    
    for I := 0 to Pdf.ImageCount - 1 do
    begin
      PdfImage := Pdf.Image[I];
      
      // Access raw image properties
      ShowMessage(Format('Image %d: %d x %d, %d bytes',
        [I, PdfImage.Width, PdfImage.Height, Length(PdfImage.Data)]));
        
      // PdfImage.Data contains raw pixel data
    end;
    
  finally
    Pdf.Active := False;
    Pdf.Free;
  end;
end;

Mostrar información de la imagen.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
procedure TFormMain.UpdatePreview(Index: Integer);
var
  Info: TImageInfo;
begin
  if (Index >= 0) and (Index < Length(FExtractedImages)) then
  begin
    Info := FExtractedImages[Index];
    
    // Update preview
    if Assigned(Info.Bitmap) then
      ImagePreview.Picture.Assign(Info.Bitmap);
      
    // Update info display
    MemoInfo.Lines.Clear;
    MemoInfo.Lines.Add('File: ' + ExtractFileName(Info.FileName));
    MemoInfo.Lines.Add('Page: ' + IntToStr(Info.PageNumber));
    MemoInfo.Lines.Add('Dimensions: ' + IntToStr(Info.Width) +
                       ' x ' + IntToStr(Info.Height));
    MemoInfo.Lines.Add('Format: ' + Info.Format);
    if Info.Size > 0 then
      MemoInfo.Lines.Add('Size: ' + FormatFloat('#,##0', Info.Size) + ' bytes');
  end;
end;

Análisis del rango de páginas.

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.ParsePageRange(const ARange: string;
  var AStartPage, AEndPage: Integer);
var
  RangeStr: string;
  DashPos: Integer;
begin
  RangeStr := Trim(ARange);
  AStartPage := 1;
  AEndPage := -1; // -1 means extract to end
  
  if (RangeStr = '') or (UpperCase(RangeStr) = 'ALL') then
    Exit;
    
  DashPos := Pos('-', RangeStr);
  if DashPos > 0 then
  begin
    // Range format: start-end
    AStartPage := StrToIntDef(Trim(Copy(RangeStr, 1, DashPos - 1)), 1);
    AEndPage := StrToIntDef(Trim(Copy(RangeStr, DashPos + 1, Length(RangeStr))), -1);
  end
  else
  begin
    // Single page
    AStartPage := StrToIntDef(RangeStr, 1);
    AEndPage := AStartPage;
  end;
end;

Abrir la carpeta de imágenes extraídas.

1
2
3
4
5
6
7
procedure TFormMain.ButtonOpenFolderClick(Sender: TObject);
begin
  if DirectoryExists(FCurrentOutputDir) then
    ShellExecute(Handle, 'open', PChar(FCurrentOutputDir), nil, nil, SW_SHOWNORMAL)
  else
    ShowMessage('Output directory does not exist.');
end;

Casos de uso.

  • Extracción de activos digitales. – Extraer fotos y gráficos de materiales de marketing.
  • Conversión de documentos. – Preparar imágenes para la web u otros formatos.
  • Procesamiento de archivos. – Extraer imágenes de archivos de documentos escaneados.
  • Análisis de contenido. – Extraer imágenes para aprendizaje automático o análisis.

Conclusión.

La demostración "Extract Images" muestra lo fácil que es extraer imágenes incrustadas de documentos PDF con PDFium VCL. El componente se encarga del complejo análisis de PDF mientras usted se enfoca en cómo utilizar las imágenes extraídas en su aplicación.

Combinado con la detección inteligente de formatos, puede crear herramientas profesionales de extracción de imágenes que producen resultados optimizados para cualquier caso de uso.

Explorar. Componente PDFium. Visite loslab.com y desbloquee el contenido de sus documentos PDF.