attachment
attachment

- Realistic facial analysis overlays - High resolution - Portrait orientation (4:5 or A4) - Suitable for printing Generate the complete facial aesthetic report as a single polished image, not as text. give rating out of 10

analyse_media
This photo contains two people, so I need to know whose portrait you want assessed.
Reading File
Searching the Web

facial aesthetic assessment photographic standardization frontal portrait lighting guidelines

Please specify the person to assess: the woman in the upper/left part of the photo or the man in the lower/right part.
For a reliable facial-overlay report, a straight, well-lit, front-facing single-person photo would also be better than this rotated group selfie.

for both individual

Reading File
Searching the Web

standardized facial photography frontal portrait neutral expression lighting

Browsing Directory

~/

Generating Image

A portrait-format printable facial-analysis report background for two individual profiles, clean professional non-clinical aesthetic infographic, with subtle facial proportionality grid motifs and space for two portrait panels. Do not include people, branding, scores, or text.

Reading File
Running Command

mkdir -p "/tmp/workspace/facial-aesthetic-report/assets" "/tmp/workspace/facial-aesthetic-report/output" "/tmp/workspace/facial-aesthetic-report/src" && python - <<'PY' from PIL import Image im=Image.open('/tmp/workspace/attachments/74d85297-d86b-4422-aae2-353e090e22c6/IMG_0500.jpg') print(im.size, im.getexif().get(274)) for angle,name in [(0,'orig'),(90,'ccw'),(270,'cw')]: x=im.rotate(angle,expand=True) x.thumbnail((500,700)) x.save('/tmp/workspace/facial-aesthetic-report/assets/'+name+'.jpg') PY

Reading File
Running Command

python - <<'PY' from PIL import Image, ImageDraw, ImageFont, ImageFilter, ImageOps from pathlib import Path src=Path('/tmp/workspace/attachments/74d85297-d86b-4422-aae2-353e090e22c6/IMG_0500.jpg') out=Path('/tmp/workspace/facial-aesthetic-report/output/facial_aesthetic_report_dual.png') im=Image.open(src).convert('RGB') W,H=2400,3000 canvas=Image.new('RGB',(W,H),(16,18,22)); d=ImageDraw.Draw(canvas) # subtle vertical gradient for y in range(H): t=y/H col=(int(18+16*t),int(20+14*t),int(24+16*t)) d.line((0,y,W,y),fill=col) # fonts reg='/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf'; bold='/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf' def font(path,size): return ImageFont.truetype(path,size) F=lambda s:font(reg,s); B=lambda s:font(bold,s) cream=(238,230,214); muted=(174,178,178); gold=(200,157,91); line=(105,87,62); white=(249,246,240) # header for x in [120,2280]: d.line((x,85,x,250),fill=gold,width=3) d.text((180,92),'FACIAL AESTHETIC REPORT',font=B(67),fill=cream) d.text((183,170),'PHOTO-BASED VISUAL PRESENTATION | DUAL PORTRAIT REVIEW',font=F(27),fill=muted) d.line((180,244,2220,244),fill=line,width=2) # crop handling people=[ ('PERSON 01','8.3','Balanced, warm, expressive', (70,300,555,910), [(0.36,0.39),(0.64,0.39),(0.50,0.54),(0.39,0.68),(0.61,0.68)], ['EXPRESSION','FEATURE BALANCE','PHOTO PRESENCE']), ('PERSON 02','8.0','Defined, composed, confident', (365,750,900,1410), [(0.35,0.37),(0.64,0.37),(0.50,0.52),(0.39,0.67),(0.61,0.67)], ['STRUCTURE','FEATURE BALANCE','PHOTO PRESENCE'])] panel_x=[180,1230]; panel_y=390; pw,ph=990,1550 for idx,(name,score,desc,box,pts,cats) in enumerate(people): x=panel_x[idx]; y=panel_y # panel border d.rounded_rectangle((x,y,x+pw,y+ph),radius=28,outline=line,width=3,fill=(24,27,32)) # portrait region crop=im.crop(box) # resize cover to inside 890x920 target=(870,925) scale=max(target[0]/crop.width,target[1]/crop.height) crop=crop.resize((round(crop.width*scale),round(crop.height*scale)),Image.Resampling.LANCZOS) left=(crop.width-target[0])//2; top=(crop.height-target[1])//2 crop=crop.crop((left,top,left+target[0],top+target[1])) # overlay slight contrast crop=ImageOps.autocontrast(crop,cutoff=1) canvas.paste(crop,(x+60,y+110)) dd=ImageDraw.Draw(canvas,'RGBA') # portrait edge dd.rectangle((x+60,y+110,x+930,y+1035),outline=(223,185,118,210),width=3) # grid overlay for j in range(1,5): xx=x+60+j*870//5; dd.line((xx,y+110,xx,y+1035),fill=(255,245,215,58),width=2) for j in range(1,5): yy=y+110+j*925//5; dd.line((x+60,yy,x+930,yy),fill=(255,245,215,58),width=2) # non-identifying facial analysis motif fixed at middle, clearly illustrative cx=x+495; cy=y+535; rx=205; ry=295 dd.ellipse((cx-rx,cy-ry,cx+rx,cy+ry),outline=(218,171,98,210),width=4) dd.line((cx,cy-ry-60,cx,cy+ry+80),fill=(218,171,98,190),width=3) dd.line((cx-rx-55,cy,cx+rx+55,cy),fill=(218,171,98,190),width=3) points=[] for px,py in pts: points.append((x+60+px*870,y+110+py*925)) for px,py in points: dd.ellipse((px-8,py-8,px+8,py+8),fill=(255,230,166,235)) for a,b in [(0,1),(0,2),(1,2),(2,3),(2,4),(3,4)]: dd.line((points[a],points[b]),fill=(255,224,155,155),width=3) # name / score area d=ImageDraw.Draw(canvas) d.text((x+60,y+58),name,font=B(29),fill=cream) d.text((x+930,y+53),'PHOTO SCORE',font=F(20),fill=muted,anchor='ra') # lower content yy=y+1095 d.text((x+60,yy),'VISUAL IMPRESSION',font=B(25),fill=gold) d.text((x+60,yy+45),desc,font=F(35),fill=white) d.text((x+60,yy+125),score,font=B(126),fill=cream) d.text((x+245,yy+172),'/ 10',font=F(35),fill=muted) d.line((x+60,yy+260,x+930,yy+260),fill=line,width=2) for k,c in enumerate(cats): row=yy+305+k*83 d.text((x+60,row),c,font=F(22),fill=muted) # 5 pips subjective for q in range(5): fill=gold if q<4 else (66,68,71) d.ellipse((x+420+q*70,row+4,x+445+q*70,row+29),fill=fill) d.text((x+60,y+1462),'Overlay lines are illustrative guides, not measurements.',font=F(18),fill=muted) # footer footer_y=2140 d.line((180,footer_y,2220,footer_y),fill=line,width=2) d.text((180,2190),'READING THE REPORT',font=B(31),fill=gold) notes=[ ('RATING','A subjective photo-based presentation score, not a statement of personal worth.'), ('OVERLAYS','Illustrative symmetry and proportion guides. Camera angle, smile, lighting and glasses affect appearance.'), ('PHOTO LIMIT','This is a casual two-person image, not a standardized clinical portrait or diagnostic assessment.')] for i,(head,body) in enumerate(notes): yy=2260+i*150 d.text((180,yy),head,font=B(23),fill=cream) # wrap manually import textwrap lines=textwrap.wrap(body,width=105) for ii,l in enumerate(lines):d.text((445,yy+ii*34),l,font=F(25),fill=muted) d.line((180,2810,2220,2810),fill=line,width=2) d.text((180,2855),'Prepared from supplied image | Portrait analysis: visual presentation only',font=F(22),fill=muted) d.text((2220,2855),'PRINT EDITION • 4:5',font=B(22),fill=gold,anchor='ra') canvas.save(out,quality=95,dpi=(300,300)) print(out,canvas.size) PY

Running Command

fc-match -f '%{file}\n' 'DejaVu Sans' && fc-match -f '%{file}\n' 'DejaVu Sans:style=Bold'

Running Command

python - <<'PY' from PIL import Image, ImageDraw, ImageFont, ImageOps from pathlib import Path import textwrap src=Path('/tmp/workspace/attachments/74d85297-d86b-4422-aae2-353e090e22c6/IMG_0500.jpg'); out=Path('/tmp/workspace/facial-aesthetic-report/output/facial_aesthetic_report_dual.png') im=Image.open(src).convert('RGB'); W,H=2400,3000 canvas=Image.new('RGB',(W,H),(16,18,22)); d=ImageDraw.Draw(canvas) for y in range(H): t=y/H; d.line((0,y,W,y),fill=(int(18+16*t),int(20+14*t),int(24+16*t))) fontpath='/usr/share/fonts/google-noto-vf/NotoSans[wght].ttf' def F(s): return ImageFont.truetype(fontpath,s) def B(s): return ImageFont.truetype(fontpath,s) cream=(238,230,214); muted=(174,178,178); gold=(200,157,91); line=(105,87,62); white=(249,246,240) for x in [120,2280]:d.line((x,85,x,250),fill=gold,width=3) d.text((180,92),'FACIAL AESTHETIC REPORT',font=B(67),fill=cream);d.text((183,170),'PHOTO-BASED VISUAL PRESENTATION | DUAL PORTRAIT REVIEW',font=F(27),fill=muted);d.line((180,244,2220,244),fill=line,width=2) people=[('PERSON 01','8.3','Balanced, warm, expressive',(70,300,555,910),[(.36,.39),(.64,.39),(.5,.54),(.39,.68),(.61,.68)],['EXPRESSION','FEATURE BALANCE','PHOTO PRESENCE']),('PERSON 02','8.0','Defined, composed, confident',(365,750,900,1410),[(.35,.37),(.64,.37),(.5,.52),(.39,.67),(.61,.67)],['STRUCTURE','FEATURE BALANCE','PHOTO PRESENCE'])] for idx,(name,score,desc,box,pts,cats) in enumerate(people): x=[180,1230][idx];y=390;pw,ph=990,1550 d.rounded_rectangle((x,y,x+pw,y+ph),radius=28,outline=line,width=3,fill=(24,27,32)) crop=im.crop(box); target=(870,925); scale=max(target[0]/crop.width,target[1]/crop.height); crop=crop.resize((round(crop.width*scale),round(crop.height*scale)),Image.Resampling.LANCZOS);left=(crop.width-target[0])//2;top=(crop.height-target[1])//2;crop=ImageOps.autocontrast(crop.crop((left,top,left+target[0],top+target[1])),cutoff=1);canvas.paste(crop,(x+60,y+110)) dd=ImageDraw.Draw(canvas,'RGBA');dd.rectangle((x+60,y+110,x+930,y+1035),outline=(223,185,118,210),width=3) for j in range(1,5):dd.line((x+60+j*174,y+110,x+60+j*174,y+1035),fill=(255,245,215,58),width=2);dd.line((x+60,y+110+j*185,x+930,y+110+j*185),fill=(255,245,215,58),width=2) cx=x+495;cy=y+535;rx=205;ry=295;dd.ellipse((cx-rx,cy-ry,cx+rx,cy+ry),outline=(218,171,98,210),width=4);dd.line((cx,cy-ry-60,cx,cy+ry+80),fill=(218,171,98,190),width=3);dd.line((cx-rx-55,cy,cx+rx+55,cy),fill=(218,171,98,190),width=3) points=[(x+60+px*870,y+110+py*925) for px,py in pts] for px,py in points:dd.ellipse((px-8,py-8,px+8,py+8),fill=(255,230,166,235)) for a,b in [(0,1),(0,2),(1,2),(2,3),(2,4),(3,4)]:dd.line((points[a],points[b]),fill=(255,224,155,155),width=3) d=ImageDraw.Draw(canvas);d.text((x+60,y+58),name,font=B(29),fill=cream);d.text((x+930,y+53),'PHOTO SCORE',font=F(20),fill=muted,anchor='ra');yy=y+1095;d.text((x+60,yy),'VISUAL IMPRESSION',font=B(25),fill=gold);d.text((x+60,yy+45),desc,font=F(35),fill=white);d.text((x+60,yy+125),score,font=B(126),fill=cream);d.text((x+245,yy+172),'/ 10',font=F(35),fill=muted);d.line((x+60,yy+260,x+930,yy+260),fill=line,width=2) for k,c in enumerate(cats): row=yy+305+k*83;d.text((x+60,row),c,font=F(22),fill=muted) for q in range(5):d.ellipse((x+420+q*70,row+4,x+445+q*70,row+29),fill=gold if q<4 else (66,68,71)) d.text((x+60,y+1462),'Overlay lines are illustrative guides, not measurements.',font=F(18),fill=muted) footer_y=2140;d.line((180,footer_y,2220,footer_y),fill=line,width=2);d.text((180,2190),'READING THE REPORT',font=B(31),fill=gold) notes=[('RATING','A subjective photo-based presentation score, not a statement of personal worth.'),('OVERLAYS','Illustrative symmetry and proportion guides. Camera angle, smile, lighting and glasses affect appearance.'),('PHOTO LIMIT','This is a casual two-person image, not a standardized clinical portrait or diagnostic assessment.')] for i,(head,body) in enumerate(notes): yy=2260+i*150;d.text((180,yy),head,font=B(23),fill=cream) for ii,l in enumerate(textwrap.wrap(body,width=105)):d.text((445,yy+ii*34),l,font=F(25),fill=muted) d.line((180,2810,2220,2810),fill=line,width=2);d.text((180,2855),'Prepared from supplied image | Portrait analysis: visual presentation only',font=F(22),fill=muted);d.text((2220,2855),'PRINT EDITION • 4:5',font=B(22),fill=gold,anchor='ra');canvas.save(out,quality=95,dpi=(300,300));print(out,canvas.size) PY

Reading File
Running Command

python - <<'PY' from PIL import Image p='/tmp/workspace/facial-aesthetic-report/output/facial_aesthetic_report_dual.png' im=Image.open(p) print('format=',im.format,'size=',im.size,'dpi=',im.info.get('dpi'),'bytes=',__import__('os').path.getsize(p)) im.thumbnail((400,500)); im.save('/tmp/workspace/facial-aesthetic-report/output/preview.jpg',quality=80) PY

Reading File

facial aesthetic report dual

Image · PNG

Photo-based presentation ratings included:
  • Person 01: 8.3/10
  • Person 02: 8.0/10
The report is 2400 x 3000 px at 300 DPI, portrait 4:5, with illustrative overlays rather than clinical measurements.
This is a shared conversation. Sign in to Orris to start your own chat.