Spaces:
Sleeping
Sleeping
| 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) | |
| def index(): | |
| return render_template('index.html') | |
| 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}) | |
| 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) | |
| def serve_watermarked(filename): | |
| return send_file(os.path.join(UPLOAD_FOLDER, filename)) | |
| def serve_thumbnail(filename): | |
| return send_file(os.path.join(THUMBNAIL_FOLDER, filename)) | |
| 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) |