from flask import Flask, request, render_template, send_file, url_for, redirect, jsonify from PIL import Image, ImageDraw, ImageFont, ImageEnhance import io import os import zipfile import base64 # Enable detailed logging for debugging import logging logging.basicConfig(level=logging.DEBUG) app = Flask(__name__) app.config['DEBUG'] = True # This enables debug mode for Flask # Configure upload folders with absolute paths in /tmp UPLOAD_FOLDER = '/tmp/watermarked_images' THUMBNAIL_FOLDER = '/tmp/thumbnails' # Ensure directories exist with proper permissions os.makedirs(UPLOAD_FOLDER, mode=0o777, exist_ok=True) os.makedirs(THUMBNAIL_FOLDER, mode=0o777, exist_ok=True) # Add zip to Jinja2 globals app.jinja_env.globals.update(zip=zip) def get_watermark_position(img_width, img_height, wm_width, wm_height, position): if position == "top-left": return 10, 10 elif position == "top-right": return img_width - wm_width - 10, 10 elif position == "center": return (img_width - wm_width) // 2, (img_height - wm_height) // 2 elif position == "bottom-left": return 10, img_height - wm_height - 10 elif position == "bottom-right": return img_width - wm_width - 10, img_height - wm_height - 10 else: return img_width - wm_width - 10, img_height - wm_height - 10 def add_watermark(image, watermark_text=None, watermark_image=None, text_position="bottom-right", image_position="bottom-right", text_transparency=100, image_transparency=100, text_size=1.0, image_size=1.0): with Image.open(image).convert("RGBA") as img: drawing = ImageDraw.Draw(img) width, height = img.size if watermark_text: font_size = max(10, int(min(width, height) * 0.05 * text_size)) try: # Try multiple font paths font_paths = [ os.path.join(BASE_DIR, 'fonts', 'LiberationSans-Regular.ttf'), "/usr/share/fonts/truetype/liberation/LiberationSans-Regular.ttf", "/usr/share/fonts/liberation/LiberationSans-Regular.ttf" ] font = None for path in font_paths: if os.path.exists(path): font = ImageFont.truetype(path, font_size) break if font is None: font = ImageFont.load_default() except Exception: font = ImageFont.load_default() print("Using default font") text = watermark_text textbbox = drawing.textbbox((0, 0), text, font=font) textwidth = textbbox[2] - textbbox[0] textheight = textbbox[3] - textbbox[1] x, y = get_watermark_position(width, height, textwidth, textheight, text_position) text_overlay = Image.new('RGBA', img.size, (255, 255, 255, 0)) text_drawing = ImageDraw.Draw(text_overlay) text_drawing.text((x, y), text, font=font, fill=(255, 255, 255, int(255 * text_transparency / 100))) img = Image.alpha_composite(img, text_overlay) if watermark_image: wm_width = max(50, int(min(width, height) * 0.1 * image_size)) wm_height = max(50, int(min(width, height) * 0.1 * image_size)) with Image.open(watermark_image).convert("RGBA") as wm_img: wm_img = wm_img.resize((wm_width, wm_height)) if image_transparency < 100: alpha = wm_img.split()[3] alpha = ImageEnhance.Brightness(alpha).enhance(image_transparency / 100) wm_img.putalpha(alpha) x, y = get_watermark_position(width, height, wm_width, wm_height, image_position) img.alpha_composite(wm_img, (x, y)) watermarked_image = io.BytesIO() img.save(watermarked_image, format='PNG') watermarked_image.seek(0) return watermarked_image def create_thumbnail(image_path, thumbnail_path, size=(150, 150)): with Image.open(image_path) as img: img.thumbnail(size) if img.mode == 'RGBA': img = img.convert('RGB') img.save(thumbnail_path) @app.route('/') def index(): return render_template('index.html') @app.route('/preview', methods=['POST']) def preview(): files = request.files.getlist('files') if not files or not files[0].filename: return jsonify({'error': 'No file uploaded'}), 400 watermark_text = request.form.get('watermark_text') watermark_image = request.files.get('watermark_image') text_position = request.form.get('text_position', 'bottom-right') image_position = request.form.get('image_position', 'bottom-right') text_transparency = int(request.form.get('text_transparency', 100)) image_transparency = int(request.form.get('image_transparency', 100)) text_size = float(request.form.get('text_size', 1.0)) image_size = float(request.form.get('image_size', 1.0)) preview_urls = [] for file in files: watermarked_image = add_watermark(file, watermark_text, watermark_image, text_position, image_position, text_transparency, image_transparency, text_size, image_size) # Convert the image to base64 for preview img_base64 = base64.b64encode(watermarked_image.getvalue()).decode('utf-8') preview_url = f"data:image/png;base64,{img_base64}" preview_urls.append(preview_url) return jsonify({'preview_urls': preview_urls}) @app.route('/upload', methods=['POST']) def upload(): files = request.files.getlist('files') watermark_text = request.form.get('watermark_text') watermark_image = request.files.get('watermark_image') text_position = request.form.get('text_position', 'bottom-right') image_position = request.form.get('image_position', 'bottom-right') text_transparency = int(request.form.get('text_transparency', 100)) image_transparency = int(request.form.get('image_transparency', 100)) text_size = float(request.form.get('text_size', 1.0)) image_size = float(request.form.get('image_size', 1.0)) watermarked_file_urls = [] thumbnail_urls = [] watermarked_file_paths = [] if not files or not files[0].filename: return "No files uploaded", 400 for file in files: watermarked_file = add_watermark(file, watermark_text, watermark_image, text_position, image_position, text_transparency, image_transparency, text_size, image_size) filename = f"watermarked_{file.filename}" filepath = os.path.join(UPLOAD_FOLDER, filename) with open(filepath, 'wb') as f: f.write(watermarked_file.getbuffer()) watermarked_file_urls.append(url_for('serve_watermarked', filename=filename)) watermarked_file_paths.append(filepath) thumbnail_path = os.path.join(THUMBNAIL_FOLDER, filename) create_thumbnail(filepath, thumbnail_path) thumbnail_urls.append(url_for('serve_thumbnail', filename=filename)) zip_filename = "watermarked_images.zip" zip_filepath = os.path.join(UPLOAD_FOLDER, zip_filename) with zipfile.ZipFile(zip_filepath, 'w') as zipf: for file_path in watermarked_file_paths: zipf.write(file_path, os.path.basename(file_path)) zip_url = url_for('download_file', filename=zip_filename) return render_template('results.html', thumbnail_urls=thumbnail_urls, watermarked_file_urls=watermarked_file_urls, zip_url=zip_url) @app.route('/watermarked/') def serve_watermarked(filename): return send_file(os.path.join(UPLOAD_FOLDER, filename)) @app.route('/thumbnail/') def serve_thumbnail(filename): return send_file(os.path.join(THUMBNAIL_FOLDER, filename)) @app.route('/download/') def download_file(filename): return send_file(os.path.join(UPLOAD_FOLDER, filename), as_attachment=True) if __name__ == '__main__': # Use the port that Hugging Face Spaces expects port = int(os.environ.get('PORT', 7860)) app.run(host='0.0.0.0', port=port)