# -*- coding: utf-8 -*- """Фоны adaptive-иконки: градиент под акцент темы + радиальное свечение + тень от логотипа.""" from PIL import Image, ImageDraw, ImageFilter import numpy as np, os TH = r"C:\radiOLA\design\logos\gen\themed" DRW = r"C:\radiOLA\app\src\main\res\drawable-nodpi" PREV = os.environ["LOCALAPPDATA"] + r"\Temp\radiola_bg_preview.png" S = 432 THEMES = [ ("forest", (0xA8,0xE0,0x5F), (0x0C,0x14,0x10)), ("ocean", (0x4F,0xD6,0xE0), (0x0A,0x0F,0x1A)), ("sunset", (0xFF,0x8A,0x5B), (0x1A,0x0F,0x0C)), ("amethyst",(0xB3,0x88,0xFF), (0x12,0x0E,0x1A)), ("neon", (0xFF,0x4D,0x9D), (0x0D,0x0A,0x12)), ("amber", (0xFF,0xC2,0x47), (0x14,0x11,0x0A)), ("ice", (0x7F,0xB3,0xFF), (0x0C,0x10,0x14)), ("rose", (0xFF,0x7E,0xA8), (0x16,0x0E,0x12)), ] def lerp(a,b,t): return tuple(a[i]+(b[i]-a[i])*t for i in range(3)) yy,xx = np.mgrid[0:S,0:S] cx,cy=S*0.5,S*0.46 rad = np.sqrt((xx-cx)**2+(yy-cy)**2)/(S*0.62) # 0 в центре → ~1 к краю diag = (xx+yy)/(2*S) # 0 верх-лево → 1 низ-право def make_bg(accent, bg): acc=np.array(accent,float); base=np.array(bg,float) # 1) база: лёгкий диагональный градиент (верх чуть светлее с оттенком акцента, низ темнее) top = lerp(bg, accent, 0.10); top=np.array([min(255,c*1.15) for c in top]) bot = np.array([c*0.7 for c in bg]) g = diag[...,None] img = top*(1-g) + bot*g # 2) радиальное акцентное свечение в центре glow = np.clip(1-rad,0,1)**1.7 img = img + (acc-img)*(glow[...,None]*0.30) # 3) виньетка по углам vig = np.clip(rad-0.6,0,1) img = img*(1-vig[...,None]*0.35) return Image.fromarray(np.clip(img,0,255).astype("uint8"),"RGB").convert("RGBA") def r_shadow(theme): """Мягкая тень от логотипа (силуэт R), запечённая в фон.""" logo=Image.open(os.path.join(TH,f"logo_{theme}.png")).convert("RGBA") logo=logo.crop(logo.getbbox()) target=196; sc=target/max(logo.size) logo=logo.resize((int(logo.width*sc),int(logo.height*sc))) sh=Image.new("RGBA",(S,S),(0,0,0,0)) # силуэт из альфы sil=Image.new("RGBA",(S,S),(0,0,0,0)) a=logo.split()[3] blk=Image.new("RGBA",logo.size,(0,0,0,150)) sil.paste(blk,((S-logo.width)//2+7,(S-logo.height)//2+14),a) # сдвиг вниз-вправо sil=sil.filter(ImageFilter.GaussianBlur(16)) return sil cols=4; rows=2; pad=16 sheet=Image.new("RGB",(cols*S//2+(cols+1)*pad, rows*S//2+(rows+1)*pad),(28,28,32)) for i,(name,acc,bg) in enumerate(THEMES): base=make_bg(acc,bg) base.alpha_composite(r_shadow(name)) base.convert("RGB").save(os.path.join(DRW,f"ic_bg_{name}.png")) # превью: фон + foreground + круглая маска fg=Image.open(os.path.join(DRW,f"ic_fg_{name}.png")).convert("RGBA") full=base.copy(); full.alpha_composite(fg) mask=Image.new("L",(S,S),0); ImageDraw.Draw(mask).ellipse([0,0,S,S],fill=255) out=Image.new("RGB",(S,S),(28,28,32)); out.paste(full.convert("RGB"),(0,0),mask) out=out.resize((S//2,S//2)) r=i//cols; c=i%cols; x=pad+c*(S//2+pad); y=pad+r*(S//2+pad) sheet.paste(out,(x,y)) sheet.save(PREV) print("bg generated + preview", PREV)