import numpy as np
from PIL import Image, ImageDraw, ImageFont
import random
def generate_random_color():
return np.array([random.uniform(0.3, 0.9) * 255 for _ in range(3)], dtype=np.float32)
def generate_gaussian_mask(height, width, center_x, center_y, std_x, std_y):
y = np.linspace(0, height - 1, height)
x = np.linspace(0, width - 1, width)
x, y = np.meshgrid(x, y)
gaussian = np.exp(-(((x - center_x)**2) / (2 * std_x*2) + ((y - center_y)**2) / (2 * std_y*2)))
return gaussian
def apply_blob_with_alpha(image, color, alpha_mask):
for c in range(3): # RGB channels
image[:, :, c] = alpha_mask[:, :, 0] * color[c] + (1 - alpha_mask[:, :, 0]) * image[:, :, c]
return image
def overlay_centered_text(pil_img, text, font_path=None, font_size=100):
draw = ImageDraw.Draw(pil_img)
try:
font = ImageFont.truetype(font_path, font_size) if font_path else ImageFont.load_default(font_size)
except Exception as e:
print(f"Warning: Failed to load font. Using default. Error: {e}")
font = ImageFont.load_default(font_size)
bbox = draw.textbbox((0, 0), text, font=font)
text_width = bbox[2] - bbox[0]
text_height = bbox[3] - bbox[1]
img_width, img_height = pil_img.size
position = ((img_width - text_width) // 2, (img_height - text_height) // 2)
draw.text(position, text, font=font, fill=(255, 255, 255))
return pil_img
def generate_rounded_edge_alpha_mask(height, width, border_px=30, radius=30):
"""
Creates an alpha mask with:
- Transparent border of size border_px
- Rounded corners with radius radius
"""
# Start with fully transparent mask
mask = Image.new('L', (width, height), 0)
draw = ImageDraw.Draw(mask)
# Define rectangle box for opaque area (inset by border_px)
rect = [border_px, border_px, width - border_px, height - border_px]
# Draw rounded rectangle filled white (opaque)
draw.rounded_rectangle(rect, radius=radius, fill=255)
return np.array(mask)
def generate_soft_gaussian_gradient(
width=1080,
height=1920,
num_blobs=5,
text=None,
font_path=None,
font_size=100,
output_path="gradient_with_transparent_edges.png"
):
image = np.ones((height, width, 3), dtype=np.float32) * 255
for _ in range(num_blobs):
center_x = random.randint(0, width)
center_y = random.randint(0, height)
std_x = random.uniform(10.2, 100.4) * width
std_y = random.uniform(10.2, 100.4) * height
color = generate_random_color()
alpha_mask = generate_gaussian_mask(height, width, center_x, center_y, std_x, std_y)[..., np.newaxis]
image = apply_blob_with_alpha(image, color, alpha_mask)
# After gradient creation...
image = np.clip(image, 0, 255).astype(np.uint8)
# Add hard-edge transparency
alpha_channel = generate_rounded_edge_alpha_mask(height, width, border_px=30, radius=30)
rgba = np.dstack((image, alpha_channel))
# Convert to RGBA image
final_image = Image.fromarray(rgba, mode='RGBA')
# Optional text
if text:
final_image = overlay_centered_text(final_image, text, font_path, font_size)
# Save image
final_image.save(output_path)
print(f"Image with transparent rounded edges saved to {output_path}")
# Example usage
generate_soft_gaussian_gradient(
width=1920,
height=600,
num_blobs=5,
text="Gradient Love",
font_path="Microsoft Sans Serif.ttf",
font_size=250,
output_path="gradient_with_rounded_transparency.png"
)