domingo, 19 de abril de 2026

DATOS. Archivos PDF

Bibloteca PyMuPDF (V)

Obtención y generación de imágenes

Dado que los documentos .pdf, además de texto y tablas, también pueden contener gráficos y que PyMuPDF es una herramienta que permite trabajar con este tipo de archivos de forma integral, parece conveniente terminar esta serie de entradas tratando sobre el trabajo de PyMuPDF con imágenes.

En primer lugar vamos a extraer las imágenes de un archivo .pdf para comporbar empíricamente que esto es posible y aprender cómo hacerlo. El siguiente script es un ejemplo de ello.



# 0. Bibliotecas necesarias

import fitz  # PyMuPDF
import io
from PIL import Image # Librería opcional para procesar el formato si es necesario

# 1. Acceder al objeto documento
doc = fitz.open("mi_documento.pdf")		# ruta relativa/nombre del documento .pdf sobre el que se trabaja

total_imagenes = 0  					# Iniciar el contador de img del doc

print(f"Analizando documento: {doc.name}\n")

# 2. Recorrer cada página del doc
for num_pagina, pagina in enumerate(doc):
    lista_imagenes = pagina.get_images(full=True)    # Obtener lista de imágenes de la página actual
    
    if lista_imagenes:
        cantidad_en_pagina = len(lista_imagenes)
        print(f"Página {num_pagina + 1}: se encontraron {cantidad_en_pagina} imágenes.")
        total_imagenes += cantidad_en_pagina
        
# 3. Procesar cada imagen encontrada
        for indice_img, img in enumerate(lista_imagenes):
            xref = img[0]                             # XREF es el identificador único del objeto
            base_image = doc.extract_image(xref)
            imagen_bytes = base_image["image"]
            extension = base_image["ext"] 			  # png, jpeg, etc.
            
# 4. Guardar la imagen en el disco
            nombre_archivo = f"imagen_p{num_pagina+1}_{indice_img+1}.{extension}"
            with open(nombre_archivo, "wb") as f:
                f.write(imagen_bytes)
    else:
        print(f"Página {num_pagina + 1}: no contiene imágenes.")

# 5. Informe final
print("-" * 30)
if total_imagenes > 0:
    print(f"EXTRACCIÓN COMPLETADA: Se han guardado {total_imagenes} imágenes.")
else:
    print("INFORME: El documento no contiene imágenes integradas.")

doc.close()


Este script realiza dos funciones: extrae las imágenes que obtiene del documento y realiza el recuento parcial (por página) y total (todo el documento) de ellas. Las imágenes las copia como archivos .jpg en el directorio del script, y la información la imprime directamente en pantalla (cmd o shell). Por razones que no están del todo claras, pero que se relacionan con la forma en que fue creado el .pdf, este script extrae una imagen por cada página del documento aunque visualmente sólo existe una sobre (en la primera página). Dado que no es una cuestión que ahora resulta de interés y que podría implicar deternerse demasiado en cuestiones que actualmente son secundarias, he preferido no ahondar en cómo resolver este problema.

Tengo más interés en tratar una segunda cuestión relacionada con las imágenes y el uso de PyMuPDF, como es la funcionlidad que esta biblioteca nos ofrece de crear una imagen de cada una de las páginas del documento, cuestión esta que da respuesta a lo que dejé pendiente en esta entrada en que la que se abordó el acceso de datos de los archivos .pdf.



# 0. Importar biblitecas necesarias

import fitz  # PyMuPDF

# 1. Abrir el documento

pdf_path = "mi_documento.pdf"	#Intoduce aquí el nombre o la ruta relativa de tu archivo .pdf
doc = fitz.open(pdf_path)
total_paginas = len(doc)

print(f"Documento cargado: {pdf_path}")
print(f"El archivo tiene {total_paginas} páginas (del 1 al {total_paginas}).")

# 2. Bucle de solicitud de página a imagen

while True:
    print("\n" + "-"*40)
    entrada = input("Indica el número de página a extraer (o escribe 'salir' para finalizar): ").lower()

    if entrada == "salir":
        break

    if not entrada.isdigit():       # Validar que la entrada sea un número
        print("Error: Por favor, introduce un número válido.")
        continue
    num_pag = int(entrada)

# 3. Validar rango de páginas (ajustando a índice 0)

    if 1 <= num_pag <= total_paginas:
        pagina = doc[num_pag - 1]
        
# 4. Mejorar la resolución (Zoom de 2x)
    
        matriz = fitz.Matrix(2, 2)          # Por defecto se renderiza a 72 DPI. Multiplicamos por 2 para mayor nitidez.
        pix = pagina.get_pixmap(matrix=matriz)
        
# 5. Guardar la imagen en directorio del script (en formato .png)

        nombre_salida = f"captura_pagina_{num_pag}.png"
        pix.save(nombre_salida)
        
        print(f"¡Éxito! La página {num_pag} ha sido guardada como '{nombre_salida}'.")
    else:
        print(f"Error: La página {num_pag} no existe. El rango es 1-{total_paginas}.")

# 6. Cerrar recursos

doc.close()
print("Script finalizado.")
  

En este caso he desarrollado una especie de utilidad para para facilitar al usuario la conversión a imagen (.npg) de las páginas que desee del documento .pdf sobre el que decida trabajar. Esto supone complicar un poco más el script al introducir el procedimiento cíclico de input, pero da utilidad inmediata al script. Los archivos de imagen generados se guardan directa y automáticamente en la raiz de la ruta en que se encuentra el script.

No hay comentarios:

Publicar un comentario

Comenta esta entrada