from PIL import Image, ImageDraw, ImageFilter import math W, H = 1400, 520 img = Image.new("RGBA", (W, H), (0, 0, 0, 255)) # Dark background gradient for y in range(H): ratio = y / H r = int(6 + ratio * 10) g = int(5 + ratio * 7) b = int(12 + ratio * 18) for x in range(W): xr = abs(x - W/2) / (W/2) rd = int(r * (1 - xr * 0.4)) gd = int(g * (1 - xr * 0.4)) bd = int(b * (1 - xr * 0.3)) img.putpixel((x, y), (max(0,rd), max(0,gd), max(0,bd), 255)) draw = ImageDraw.Draw(img) # Glass panel GL = 460 GR = 940 # Glass fill - subtle blue-grey glass_layer = Image.new("RGBA", (W, H), (0,0,0,0)) gd2 = ImageDraw.Draw(glass_layer) for x in range(GL, GR): ratio = (x - GL) / (GR - GL) t = math.sin(ratio * math.pi) r = int(20 + 22 * t) g = int(28 + 30 * t) b = int(50 + 48 * t) for y in range(H): yr = y / H yt = math.sin(yr * math.pi) alpha = int(140 + 60 * t) glass_layer.putpixel((x,y), (r, g, b, alpha)) img = Image.alpha_composite(img, glass_layer) draw = ImageDraw.Draw(img) # Glass edge lines for i in range(3): alpha = 180 - i*50 draw.line([(GL+i, 0), (GL+i, H)], fill=(100, 150, 220, alpha), width=1) draw.line([(GR-i, 0), (GR-i, H)], fill=(100, 150, 220, alpha), width=1) # Golden eye glow from inside glow_cx = (GL + GR) // 2 glow_cy = H // 2 - 10 for rad in range(300, 2, -6): intensity = (1 - rad/300) ** 2.2 rc = int(220 * intensity) gc = int(100 * intensity) bc = int(5 * intensity) ac = int(22 * intensity) layer = Image.new("RGBA", (W, H), (0,0,0,0)) ld = ImageDraw.Draw(layer) ld.ellipse([glow_cx-rad, glow_cy-int(rad*0.65), glow_cx+rad, glow_cy+int(rad*0.65)], fill=(rc,gc,bc,ac)) img = Image.alpha_composite(img, layer) draw = ImageDraw.Draw(img) # Two glowing golden eyes for eye_x in [glow_cx - 58, glow_cx + 58]: for rad in range(25, 0, -1): intensity = (1 - rad/25) ** 1.2 layer = Image.new("RGBA", (W, H), (0,0,0,0)) ld = ImageDraw.Draw(layer) ld.ellipse([eye_x-rad, glow_cy-int(rad*0.55), eye_x+rad, glow_cy+int(rad*0.55)], fill=(int(255*intensity), int(170*intensity), int(30*intensity), int(210*intensity))) img = Image.alpha_composite(img, layer) draw = ImageDraw.Draw(img) # ---- DRAW HANDS ---- def draw_hand(base_img, anchor_x, anchor_y, flip=False): d = ImageDraw.Draw(base_img) skin = (192, 170, 150) skin_mid = (170, 148, 128) skin_dark = (130, 108, 90) nail_col = (208, 192, 178) sign = -1 if flip else 1 # Finger definitions: x_offset (from anchor), y_top, width, height # fingers go LEFT to RIGHT before flip: pinky, ring, middle, index, thumb fingers = [ (-52, 18, 19, 100), (-27, 2, 22, 120), (0, -8, 24, 130), (27, 2, 22, 118), (60, 35, 18, 80), ] palm_h = 110 palm_top = anchor_y + 95 # Palm polygon if not flip: palm = [ (anchor_x - 68, palm_top), (anchor_x + 72, palm_top), (anchor_x + 68, palm_top + palm_h), (anchor_x - 70, palm_top + palm_h), ] else: palm = [ (anchor_x + 68, palm_top), (anchor_x - 72, palm_top), (anchor_x - 68, palm_top + palm_h), (anchor_x + 70, palm_top + palm_h), ] d.polygon(palm, fill=skin_mid) for (ox, oy, fw, fh) in fingers: fx = anchor_x + (ox * sign) fy = anchor_y + oy # Finger body d.rectangle([fx - fw//2, fy + 12, fx + fw//2, fy + fh], fill=skin) # Rounded top d.ellipse([fx - fw//2, fy, fx + fw//2, fy + 24], fill=skin) # Fingernail nw = fw - 5 d.rounded_rectangle([fx - nw//2, fy + 2, fx + nw//2, fy + 16], radius=4, fill=nail_col) # Knuckle shadows for kpct in [0.45, 0.75]: ky = int(fy + fh * kpct) d.arc([fx - fw//2 + 2, ky - 4, fx + fw//2 - 2, ky + 6], start=180, end=360, fill=skin_dark, width=1) # Finger shadow sides d.line([(fx + fw//2, fy + 12), (fx + fw//2, fy + fh)], fill=skin_dark, width=2) # Wrist wrist_w = 55 if not flip: d.rectangle([anchor_x - wrist_w, palm_top + palm_h, anchor_x + wrist_w, palm_top + palm_h + 50], fill=skin_dark) else: d.rectangle([anchor_x - wrist_w, palm_top + palm_h, anchor_x + wrist_w, palm_top + palm_h + 50], fill=skin_dark) # Left hand tips touching left glass edge draw_hand(img, GL + 10, 70, flip=False) # Right hand tips touching right glass edge (mirrored) draw_hand(img, GR - 10, 70, flip=True) draw = ImageDraw.Draw(img) # Soft condensation near hands fog = Image.new("RGBA", (W, H), (0,0,0,0)) fd = ImageDraw.Draw(fog) fd.ellipse([GL - 40, 180, GL + 80, 360], fill=(160, 185, 220, 20)) fd.ellipse([GR - 80, 180, GR + 40, 360], fill=(160, 185, 220, 20)) img = Image.alpha_composite(img, fog) # Vignette vig = Image.new("RGBA", (W, H), (0,0,0,0)) for i in range(200): alpha = int(130 * (i/200)**2) # top vig_d = ImageDraw.Draw(vig) for x in range(W): for edge_dist in range(60): alpha_v = int(180 * (1 - edge_dist/60)**2) if edge_dist < H: vig.putpixel((x, edge_dist), (0,0,0,alpha_v)) vig.putpixel((x, H-1-edge_dist), (0,0,0, int(alpha_v * 0.5))) for y in range(H): for edge_dist in range(80): alpha_v = int(200 * (1 - edge_dist/80)**2) cur = vig.getpixel((edge_dist, y)) vig.putpixel((edge_dist, y), (0,0,0, min(255, cur[3]+alpha_v))) cur2 = vig.getpixel((W-1-edge_dist, y)) vig.putpixel((W-1-edge_dist, y), (0,0,0, min(255, cur2[3]+alpha_v))) img = Image.alpha_composite(img, vig) # Final soft blur img = img.filter(ImageFilter.GaussianBlur(radius=1.0)) img = img.convert("RGB") img.save("/home/claude/glass_hands.png", quality=97) print("Done!")