from flask import Flask, send_file, request, abort from PIL import Image, ImageDraw, ImageFont, ImageFilter, ImageEnhance from io import BytesIO from datetime import datetime import os import requests import math app = Flask(__name__) def download_font(url, filename): """Download font from URL if it doesn't exist locally""" if not os.path.exists(filename): try: response = requests.get(url) response.raise_for_status() with open(filename, 'wb') as f: f.write(response.content) return True except: return False return True def get_text_dimensions(text, font): """Get text dimensions using the new textbbox method""" bbox = font.getbbox(text) width = bbox[2] - bbox[0] height = bbox[3] - bbox[1] return width, height def create_gradient_background(width, height, start_color, end_color): """Create a beautiful gradient background""" gradient = Image.new('RGB', (width, height), start_color) draw = ImageDraw.Draw(gradient) for y in range(height): # Calculate the blend ratio ratio = y / height # Interpolate between start and end colors r = int(start_color[0] * (1 - ratio) + end_color[0] * ratio) g = int(start_color[1] * (1 - ratio) + end_color[1] * ratio) b = int(start_color[2] * (1 - ratio) + end_color[2] * ratio) draw.line([(0, y), (width, y)], fill=(r, g, b)) return gradient def add_glow_effect(img, text, font, position, color, glow_radius=3): """Add a glow effect to text""" # Create a larger image for the glow glow_img = Image.new('RGBA', (img.width + glow_radius * 4, img.height + glow_radius * 4), (0, 0, 0, 0)) glow_draw = ImageDraw.Draw(glow_img) # Draw the text multiple times with slight offsets for glow glow_x = position[0] + glow_radius * 2 glow_y = position[1] + glow_radius * 2 for offset_x in range(-glow_radius, glow_radius + 1): for offset_y in range(-glow_radius, glow_radius + 1): if offset_x != 0 or offset_y != 0: alpha = max(0, 100 - int(math.sqrt(offset_x**2 + offset_y**2) * 30)) glow_color = (*color[:3], alpha) glow_draw.text((glow_x + offset_x, glow_y + offset_y), text, font=font, fill=glow_color) # Apply blur to the glow glow_img = glow_img.filter(ImageFilter.GaussianBlur(radius=1)) # Composite the glow with the original image img_rgba = img.convert('RGBA') combined = Image.alpha_composite(img_rgba, glow_img.crop((glow_radius * 2, glow_radius * 2, glow_img.width - glow_radius * 2, glow_img.height - glow_radius * 2))) return combined.convert('RGB') def add_embossed_effect(draw, text, font, position, color, shadow_color): """Add an embossed/3D effect to text""" x, y = position # Draw bigger shadow (offset down and right) - scale with font size shadow_offset = 6 draw.text((x + shadow_offset, y + shadow_offset), text, font=font, fill=shadow_color) # Draw highlight (offset up and left) highlight_color = tuple(min(255, c + 60) for c in color) highlight_offset = 3 draw.text((x - highlight_offset, y - highlight_offset), text, font=font, fill=highlight_color) # Draw main text draw.text((x, y), text, font=font, fill=color) @app.route('/generate', methods=['GET']) def generate_card(): # Get code from query string code = request.args.get("code") if not code: return abort(400, description="Missing ?code= parameter") # Format the code with hyphens every 4 characters code = code.replace("-", "").upper() formatted_code = '-'.join([code[i:i+4] for i in range(0, len(code), 4)]) # Create card dimensions card_width, card_height = 1200, 750 # Try to load background image, otherwise create gradient try: img = Image.open("image.png").convert("RGB") img = img.resize((card_width, card_height), Image.Resampling.LANCZOS) # Enhance the background image enhancer = ImageEnhance.Contrast(img) img = enhancer.enhance(1.2) enhancer = ImageEnhance.Color(img) img = enhancer.enhance(1.1) except FileNotFoundError: # Create a stunning gradient background img = create_gradient_background( card_width, card_height, start_color=(15, 32, 68), # Deep navy blue end_color=(45, 12, 35) # Deep purple ) # Add some texture/noise overlay = Image.new('RGBA', (card_width, card_height), (0, 0, 0, 0)) overlay_draw = ImageDraw.Draw(overlay) # Add subtle geometric patterns for i in range(0, card_width, 100): for j in range(0, card_height, 100): overlay_draw.rectangle([i, j, i+2, j+2], fill=(255, 255, 255, 20)) img = Image.alpha_composite(img.convert('RGBA'), overlay).convert('RGB') draw = ImageDraw.Draw(img) # Initialize fonts with defaults first code_font = ImageFont.load_default() timestamp_font = ImageFont.load_default() title_font = ImageFont.load_default() fonts_loaded = False # Try to load premium fonts try: # Try to download Google Fonts font_urls = { 'orbitron_bold.ttf': 'https://github.com/google/fonts/raw/main/ofl/orbitron/Orbitron-Bold.ttf', 'roboto_mono.ttf': 'https://github.com/google/fonts/raw/main/apache/robotomono/RobotoMono-Regular.ttf' } for filename, url in font_urls.items(): download_font(url, filename) # Load the downloaded fonts with ULTRA MASSIVE code size for 16:9 aspect ratio code_font = ImageFont.truetype('orbitron_bold.ttf', 350) timestamp_font = ImageFont.truetype('roboto_mono.ttf', 52) title_font = ImageFont.truetype('orbitron_bold.ttf', 75) fonts_loaded = True print("✅ Premium fonts loaded successfully!") except Exception as e: print(f"⚠️ Premium font loading failed: {e}") # Fallback to system fonts try: system_fonts = [ "/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf", "/usr/share/fonts/truetype/liberation/LiberationSans-Bold.ttf", "/System/Library/Fonts/Helvetica.ttc", "/System/Library/Fonts/Arial.ttf", "C:\\Windows\\Fonts\\arial.ttf", "C:\\Windows\\Fonts\\calibri.ttf", "arial.ttf" ] for font_path in system_fonts: if os.path.exists(font_path): try: code_font = ImageFont.truetype(font_path, 350) timestamp_font = ImageFont.truetype(font_path, 52) title_font = ImageFont.truetype(font_path, 75) fonts_loaded = True print(f"✅ System font loaded: {font_path}") break except Exception as font_error: print(f"❌ Failed to load {font_path}: {font_error}") continue except Exception as system_error: print(f"⚠️ System font loading failed: {system_error}") print("📝 Using default fonts") print(f"🎨 Fonts loaded: {'Premium' if fonts_loaded else 'Default'}") # Enhanced color scheme primary_color = (0, 255, 136) # Bright green secondary_color = (255, 215, 0) # Gold accent_color = (64, 224, 255) # Sky blue text_color = (240, 240, 240) # Light gray shadow_color = (20, 20, 20) # Dark shadow # Add title with better positioning for huge code title_text = "DIGITAL ACCESS CARD" title_width, title_height = get_text_dimensions(title_text, title_font) title_x = (card_width - title_width) // 2 title_y = 40 # Add embossed effect to title add_embossed_effect(draw, title_text, title_font, (title_x, title_y), secondary_color, shadow_color) # Add bigger decorative lines around title line_y = title_y + title_height + 25 draw.rectangle([60, line_y, card_width - 60, line_y + 8], fill=primary_color) draw.rectangle([100, line_y + 15, card_width - 100, line_y + 18], fill=accent_color) # Position ULTRA MASSIVE code in center (NO CONTAINER!) code_width, code_height = get_text_dimensions(formatted_code, code_font) code_x = (card_width - code_width) // 2 code_y = (card_height - code_height) // 2 - 20 # Slight adjustment for better balance # Add ULTRA MASSIVE embossed effect directly to code (no background container) add_embossed_effect(draw, formatted_code, code_font, (code_x, code_y), primary_color, shadow_color) # Add timestamp with better positioning for massive code timestamp = datetime.now().strftime("Generated: %Y-%m-%d %H:%M:%S UTC") ts_width, ts_height = get_text_dimensions(timestamp, timestamp_font) ts_x = (card_width - ts_width) // 2 ts_y = code_y + code_height + 60 # Add bigger subtle background for timestamp ts_bg_coords = [ts_x - 30, ts_y - 18, ts_x + ts_width + 30, ts_y + ts_height + 18] draw.rectangle(ts_bg_coords, fill=(0, 0, 0, 60)) draw.text((ts_x, ts_y), timestamp, font=timestamp_font, fill=text_color) # Add bigger corner decorations corner_size = 80 corner_thickness = 8 # Top-left corner draw.rectangle([20, 20, 20 + corner_size, 20 + corner_thickness], fill=accent_color) draw.rectangle([20, 20, 20 + corner_thickness, 20 + corner_size], fill=accent_color) # Top-right corner draw.rectangle([card_width - 20 - corner_size, 20, card_width - 20, 20 + corner_thickness], fill=accent_color) draw.rectangle([card_width - 20 - corner_thickness, 20, card_width - 20, 20 + corner_size], fill=accent_color) # Bottom-left corner draw.rectangle([20, card_height - 20 - corner_thickness, 20 + corner_size, card_height - 20], fill=accent_color) draw.rectangle([20, card_height - 20 - corner_size, 20 + corner_thickness, card_height - 20], fill=accent_color) # Bottom-right corner draw.rectangle([card_width - 20 - corner_size, card_height - 20 - corner_thickness, card_width - 20, card_height - 20], fill=accent_color) draw.rectangle([card_width - 20 - corner_thickness, card_height - 20 - corner_size, card_width - 20, card_height - 20], fill=accent_color) # Add bigger serial number serial = f"SN: {datetime.now().strftime('%Y%m%d%H%M%S')}" serial_width, serial_height = get_text_dimensions(serial, timestamp_font) draw.text((card_width - serial_width - 40, card_height - serial_height - 40), serial, font=timestamp_font, fill=(150, 150, 150)) # Apply final enhancement enhancer = ImageEnhance.Sharpness(img) img = enhancer.enhance(1.1) # Return image in memory buffer = BytesIO() img.save(buffer, format="PNG", quality=95, optimize=True) buffer.seek(0) return send_file(buffer, mimetype="image/png", as_attachment=False, download_name="premium_access_card.png") @app.route('/health', methods=['GET']) def health_check(): return {"status": "healthy", "timestamp": datetime.now().isoformat()} if __name__ == '__main__': print("🚀 Premium Card Generator Starting...") print("📱 Access your cards at: http://localhost:7860/generate?code=YOUR_CODE") app.run(host='0.0.0.0', port=7860, debug=True)