From 69562fbf2264bb9ffbec188807a111e0bba93451 Mon Sep 17 00:00:00 2001 From: DigiServer Developer Date: Mon, 24 Nov 2025 22:28:44 +0200 Subject: [PATCH] updated to fullscreen view ppt --- app/blueprints/content.py | 105 +++++++++++++++++++++++++++++++++++--- 1 file changed, 97 insertions(+), 8 deletions(-) diff --git a/app/blueprints/content.py b/app/blueprints/content.py index b7c7a01..acf8efb 100644 --- a/app/blueprints/content.py +++ b/app/blueprints/content.py @@ -526,17 +526,16 @@ def process_presentation_file(filepath: str, filename: str) -> tuple[bool, str]: temp_ppt = temp_path / filename shutil.copy2(filepath, temp_ppt) - # Convert presentation to images (PNG format) - # Using LibreOffice headless mode with custom resolution + # Convert presentation to PDF first (for better quality) convert_cmd = [ libreoffice_cmd, '--headless', - '--convert-to', 'png', + '--convert-to', 'pdf', '--outdir', str(temp_path), str(temp_ppt) ] - log_action('info', f'Converting presentation to images: {filename}') + log_action('info', f'Converting presentation to PDF: {filename}') try: result = subprocess.run( @@ -550,8 +549,40 @@ def process_presentation_file(filepath: str, filename: str) -> tuple[bool, str]: log_action('error', f'LibreOffice conversion failed: {result.stderr}') return True, "Presentation accepted without conversion (conversion failed)" + # Find generated PDF file + pdf_files = list(temp_path.glob('*.pdf')) + if not pdf_files: + log_action('warning', f'No PDF generated from presentation: {filename}') + return True, "Presentation accepted without conversion" + + pdf_file = pdf_files[0] + log_action('info', f'Converting PDF to images at Full HD resolution: {pdf_file.name}') + + # Convert PDF to images using pdftoppm at Full HD resolution (1920x1080) + # Calculate DPI for Full HD output (assuming standard presentation is 10x7.5 inches) + # 1920/10 = 192 DPI for width, use 192 DPI for best quality + pdftoppm_cmd = [ + 'pdftoppm', + '-png', + '-r', '300', # High DPI for quality + '-scale-to', '1920', # Scale width to 1920px + str(pdf_file), + str(temp_path / 'slide') + ] + + result = subprocess.run( + pdftoppm_cmd, + capture_output=True, + text=True, + timeout=120 + ) + + if result.returncode != 0: + log_action('error', f'pdftoppm conversion failed: {result.stderr}') + return True, "Presentation accepted without conversion (image conversion failed)" + # Find generated PNG files - png_files = sorted(temp_path.glob('*.png')) + png_files = sorted(temp_path.glob('slide-*.png')) if not png_files: log_action('warning', f'No images generated from presentation: {filename}') @@ -561,7 +592,7 @@ def process_presentation_file(filepath: str, filename: str) -> tuple[bool, str]: upload_folder = current_app.config['UPLOAD_FOLDER'] base_name = os.path.splitext(filename)[0] - # Move converted images to upload folder + # Move converted images to upload folder and resize to exact Full HD slide_count = 0 for idx, png_file in enumerate(png_files, start=1): # Create descriptive filename @@ -570,8 +601,8 @@ def process_presentation_file(filepath: str, filename: str) -> tuple[bool, str]: shutil.move(str(png_file), destination) - # Optimize the image to Full HD (1920x1080) - optimize_image_to_fullhd(destination) + # Resize to exact Full HD dimensions (1920x1080) maintaining aspect ratio + resize_image_to_fullhd(destination) slide_count += 1 @@ -616,6 +647,64 @@ def create_fullhd_image(img): return fullhd_img +def resize_image_to_fullhd(filepath: str) -> bool: + """Resize image to exactly Full HD (1920x1080) maintaining aspect ratio with centered crop or padding.""" + try: + from PIL import Image + + img = Image.open(filepath) + target_width = 1920 + target_height = 1080 + + # Calculate aspect ratios + img_aspect = img.width / img.height + target_aspect = target_width / target_height + + if abs(img_aspect - target_aspect) < 0.01: + # Aspect ratio is very close, just resize + img_resized = img.resize((target_width, target_height), Image.Resampling.LANCZOS) + elif img_aspect > target_aspect: + # Image is wider than target, fit height and crop/pad width + new_height = target_height + new_width = int(target_height * img_aspect) + img_resized = img.resize((new_width, new_height), Image.Resampling.LANCZOS) + + # Crop to center if wider + if new_width > target_width: + left = (new_width - target_width) // 2 + img_resized = img_resized.crop((left, 0, left + target_width, target_height)) + else: + # Pad with white if narrower + result = Image.new('RGB', (target_width, target_height), (255, 255, 255)) + offset = (target_width - new_width) // 2 + result.paste(img_resized, (offset, 0)) + img_resized = result + else: + # Image is taller than target, fit width and crop/pad height + new_width = target_width + new_height = int(target_width / img_aspect) + img_resized = img.resize((new_width, new_height), Image.Resampling.LANCZOS) + + # Crop to center if taller + if new_height > target_height: + top = (new_height - target_height) // 2 + img_resized = img_resized.crop((0, top, target_width, top + target_height)) + else: + # Pad with white if shorter + result = Image.new('RGB', (target_width, target_height), (255, 255, 255)) + offset = (target_height - new_height) // 2 + result.paste(img_resized, (0, offset)) + img_resized = result + + # Save optimized image + img_resized.save(filepath, 'PNG', optimize=True, quality=95) + + return True + except Exception as e: + log_action('error', f'Image resize error: {str(e)}') + return False + + def optimize_image_to_fullhd(filepath: str) -> bool: """Optimize and resize image file to Full HD (1920x1080) maintaining aspect ratio.""" try: