print / app.py
newservers's picture
Update app.py
cee3d2a verified
Raw
History Blame Contribute Delete
11.9 kB
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)