Tools / PDF /images_to_pdf.py
jebin2's picture
image-pdf
2b3b710
"""
Images to PDF Converter Module
This module provides functionality to convert multiple images into a single PDF file.
"""
import os
from PIL import Image
from pathlib import Path
from custom_logger import logger_config
class ImagesToPDF:
"""
Convert multiple images into a single PDF file.
"""
def __init__(self):
self.current_path = os.path.abspath(os.path.join(os.path.dirname(__file__)))
self.input_dir = os.path.join(self.current_path, "input")
self.output_dir = os.path.join(self.current_path, "output")
self.supported_formats = ['jpg', 'jpeg', 'png', 'webp', 'bmp', 'gif', 'tiff', 'tif']
# Create directories if they don't exist
os.makedirs(self.input_dir, exist_ok=True)
os.makedirs(self.output_dir, exist_ok=True)
def _validate_image(self, filename: str) -> bool:
"""Check if file is a supported image format."""
ext = Path(filename).suffix.lower().lstrip('.')
return ext in self.supported_formats
def convert_to_pdf(self, image_ids: list, output_name: str = "output.pdf") -> str:
"""
Convert multiple images to a single PDF.
Args:
image_ids: List of image file IDs in the input directory
output_name: Name for the output PDF file
Returns:
Path to the generated PDF file, or None on failure
"""
try:
if not image_ids:
raise ValueError("No images provided for conversion")
images = []
first_image = None
for img_id in image_ids:
img_path = os.path.join(self.input_dir, img_id)
if not os.path.exists(img_path):
logger_config.warning(f"Image not found: {img_path}")
continue
# Open and convert image to RGB (PDF requires RGB)
img = Image.open(img_path)
# Handle transparency by converting to RGB with white background
if img.mode in ('RGBA', 'LA', 'P'):
# Create white background
background = Image.new('RGB', img.size, (255, 255, 255))
if img.mode == 'P':
img = img.convert('RGBA')
background.paste(img, mask=img.split()[-1] if img.mode == 'RGBA' else None)
img = background
elif img.mode != 'RGB':
img = img.convert('RGB')
if first_image is None:
first_image = img
else:
images.append(img)
if first_image is None:
raise ValueError("No valid images found for conversion")
# Generate output path
output_path = os.path.join(self.output_dir, output_name)
# Save as PDF
if images:
first_image.save(
output_path,
save_all=True,
append_images=images,
resolution=100.0
)
else:
first_image.save(output_path, resolution=100.0)
logger_config.success(f"PDF created successfully: {output_path}")
# Cleanup input files
for img_id in image_ids:
img_path = os.path.join(self.input_dir, img_id)
if os.path.exists(img_path):
os.unlink(img_path)
return output_path
except Exception as e:
logger_config.error(f"PDF conversion failed: {str(e)}")
return None
def upload(self, file_id: str, file_content: bytes):
"""Save uploaded file to input directory."""
file_path = os.path.join(self.input_dir, file_id)
with open(file_path, 'wb') as f:
f.write(file_content)
logger_config.info(f"File uploaded: {file_path}")