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) |