Cómo disminuir el tamaño de un archivo PDF utilizando un script en Python 3.
Es muy habitual que, para realizar una inscripción en una guardería o inscribirte en una ayuda pública necesite subir documentación escaneada en formato PDF con una limitación de tamaño. Escaneos de documentos cómo el DNI de identidad, libro de familia etc, son bastante pesados al ser documentos con pdf.
En este caso, lo mejor es comprimirlo para ocupar menos espacio y poder subirlo en la plataforma que lo soliciten Para ello, podemos utilizar una herramienta como
https://1938.com .es/reducir-pdf o, como os enseñaré en este artículo, podemos usar Python 3 para realizar esta tarea sin compartir los ficheros con una web. Puedes consultar el siguiente repositorio:
https://github.com/al118345/pdfconpython3
También os dejo el siguiente video explicativo:
https://www.youtube.com/watch?v=Qc6WG2k5tFkCompresión de ficheros en Python
A continuación, os voy a proporcionar los diferentes métodos necesarios para ejecutar el script en Python3.
#!/usr/bin/env python3
"""
Script de Python que utiliza ghoscript para comprimir ficheros PDF.
Niveles de compresión:
0: defecto
1: prepress
2: printer
3: ebook
4: screen
Dependencias: Ghostscript.
En MacOSX aplica la siguiente línea `brew install ghostscript`.
"""
import argparse
import subprocess
import os.path
import sys
import shutil
def compress(input_file_path, output_file_path, power=0):
"""Función para comprimir PDF via Ghostscript """
quality = {
0: '/default',
1: '/prepress',
2: '/printer',
3: '/ebook',
4: '/screen'
}
# Comprovamos si existe el fichero
if not os.path.isfile(input_file_path):
print("Error: invalid path for input PDF file")
sys.exit(1)
#Comprobamos si es un pdf
if input_file_path.split('.')[-1].lower() != 'pdf':
print("Error: input file is not a PDF")
sys.exit(1)
gs = get_ghostscript_path()
print("Compress PDF...")
initial_size = os.path.getsize(input_file_path)
subprocess.call([gs, '-sDEVICE=pdfwrite', '-dCompatibilityLevel=1.4',
'-dPDFSETTINGS={}'.format(quality[power]),
'-dNOPAUSE', '-dQUIET', '-dBATCH',
'-sOutputFile={}'.format(output_file_path),
input_file_path]
)
final_size = os.path.getsize(output_file_path)
ratio = 1 - (final_size / initial_size)
print("Compression by {0:.0%}.".format(ratio))
print("Final file size is {0:.1f}MB".format(final_size / 1000000))
print("Done.")
def get_ghostscript_path():
gs_names = ['gs', 'gswin32', 'gswin64']
for name in gs_names:
if shutil.which(name):
return shutil.which(name)
raise FileNotFoundError(f'No GhostScript executable was found on path ({"/".join(gs_names)})')
Método compress
La función compress tiene tres parámetros, la ruta al fichero original, la ruta dónde almacenaremos el fichero comprimido y el nivel de compresión del fichero. Por ejemplo, en el caso de querer comprimir un fichero al máximo deberemos utilizar un valor de 4 o si queremos que pierda poca calidad utilizaremos un valor 1.
El método no es muy complicado. Únicamente utiliza ghostscript con las siguientes opciones:
- -sDEVICE=pdfwrite
- -dCompatibilityLevel=1.4
- -dPDFSETTINGS=[0-4]
- dNOPAUSE
- -dQUIET
- -dBATCH
Importante, utilizar un path de salida diferente al de la entrada. Es decir, si el nombre del fichero es x el nombre de salida puede ser x-comprimido.pdf o almacenar x en otra carpeta. No sobrescribir. Una vez realizada la tarea puedes borrar el fichero original.Método get_ghostscript_path
La función get_ghostscript_path devuelve la ruta al ejecutable ghostscript.
Método Main
Un ejemplo básico de uso de la función compress lo podemos encontrar en el siguiente código:
if __name__ == '__main__':
from os import listdir
from os.path import isfile, join
path = 'ruta_a_los ficheros_originales'
path_compress = 'ruta_a_los_ficheros_comprimidos'
onlyfiles = [f for f in listdir(path) if isfile(join(path, f))]
for i in onlyfiles:
compress(path+i, path_compress+i, power=3)
En este programa recorremos todos los ficheros de una carpeta y comprimimos cada uno de los archivos pdf que vamos a encontrar. El resultado lo almacenamos en la ruta de destino.