compresorpdfnova / pdf_compressor_app.py
darkred06's picture
Update pdf_compressor_app.py
44af7ed verified
import os
import io
import subprocess
from flask import Flask, render_template, request, send_file, Response
app = Flask(__name__)
# --- FUNCIÓN DE COMPRESIÓN (USANDO GHOSTSCRIPT) ---
def compress_pdf_with_ghostscript(input_stream: io.BytesIO, quality: str) -> io.BytesIO:
"""
Comprime un PDF usando Ghostscript, forzando un perfil agresivo y baja resolución
(100 DPI) para las imágenes internas.
"""
output_stream = io.BytesIO()
input_stream.seek(0)
# Parámetros para forzar la compresión máxima
gs_command = [
"gs",
"-sDEVICE=pdfwrite",
"-dCompatibilityLevel=1.4",
# Usamos el perfil 'ebook' como base agresiva
"-dPDFSETTINGS=/ebook",
# Opciones para forzar el reescalado de imágenes a 100 DPI
"-dDownsampleColorImages=true",
"-dColorImageResolution=100",
"-dDownsampleGrayImages=true",
"-dGrayImageResolution=100",
"-dNOPAUSE", "-dBATCH", "-dQUIET",
"-sOutputFile=-", # Salida a stdout
"-" # Entrada desde stdin
]
try:
# Ejecutar el comando Ghostscript
process = subprocess.run(
gs_command,
input=input_stream.read(),
capture_output=True,
check=True
)
output_stream.write(process.stdout)
output_stream.seek(0)
return output_stream
except subprocess.CalledProcessError as e:
raise Exception(f"Error de Ghostscript: {e.stderr.decode()}")
except FileNotFoundError:
raise Exception("Ghostscript no está instalado en el servidor. (Verifica el Dockerfile)")
except Exception as e:
raise Exception(f"Error desconocido durante la compresión: {e}")
# --- RUTAS ---
@app.route('/')
def index():
"""Muestra la interfaz del compresor."""
# Asegúrate de que compressor_index.html esté en la carpeta templates/
return render_template('compressor_index.html')
@app.route('/compress', methods=['POST'])
def compress_pdf_file():
"""Ruta para recibir y comprimir el PDF subido."""
if 'pdf_file' not in request.files:
return Response('No se seleccionó ningún archivo PDF', status=400)
pdf_file = request.files['pdf_file']
quality_setting = request.form.get('quality', 'screen') # Recibe el perfil seleccionado
try:
input_stream = io.BytesIO(pdf_file.read())
# Comprimir el PDF subido
compressed_stream = compress_pdf_with_ghostscript(input_stream, quality_setting)
# Devolver el archivo comprimido
return send_file(
compressed_stream,
as_attachment=True,
download_name=f"comprimido_{pdf_file.filename}",
mimetype='application/pdf'
)
except Exception as e:
return Response(f"Error en la compresión: {str(e)}", status=500)
if __name__ == '__main__':
port = int(os.environ.get('PORT', 7860))
app.run(host='0.0.0.0', port=port, debug=False)