|
|
""" |
|
|
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'] |
|
|
|
|
|
|
|
|
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 |
|
|
|
|
|
|
|
|
img = Image.open(img_path) |
|
|
|
|
|
|
|
|
if img.mode in ('RGBA', 'LA', 'P'): |
|
|
|
|
|
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") |
|
|
|
|
|
|
|
|
output_path = os.path.join(self.output_dir, output_name) |
|
|
|
|
|
|
|
|
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}") |
|
|
|
|
|
|
|
|
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}") |
|
|
|