You are browsing as a guest. Sign up (or log in) to start making projects!

Ziyaad

@Ziyaad

Joined June 8th, 2026

  • 4Devlogs
  • 2Projects
  • 1Ships
  • 15Votes
Ship

built a web app that tells you which photo of your face to use as your profile pic.

you upload a bunch of photos, it runs face detection in your browser (no uploads, no server, no account) and scores each face on centering, size, brightness, and sharpness. the highest score wins. it tells you why in plain words.

the challenging part was getting the scoring to feel honest instead of random. sharpness especially, I had to measure contrast between neighboring pixels to get it right.

proud of the fact that nothing leaves your browser. your photos never touch a server. close the tab, it's gone.

to test it: just drag in 3-5 photos of your face. good luck and thank you

-Ziyaad :)

  • 4 devlogs
  • 6h
Try project → See source code →
Open comments for this post

2h 46m 2s logged

PFP Studio Devlog #3 (idk if anyone will ever read this)

Live link: https://pfp-studio-fawn.vercel.app/

TL;DR

  • the winner explanation sounds like a person now, not a form letter
  • photos with no face get a card instead of silently vanishing
  • rebuilt the whole upload screen into orbiting rings of your photos
  • shipped to vercel, after one line of css put up a fight

The Justification

before, the winner card said the exact same thing every single time. “this photo is the best because the face is well-centered in the frame.” every photo. every run. it read like a robot filling out a form.

so i gave each check its own pool of phrasings, picked at random, and made it call out two strengths instead of one. now it says stuff like “easy top pick. face sits right in the middle, plus crisp, every detail holds up.”

reads like a person wrote it. which was the whole point.


No Face? Still Get a Card

what’s the point of ranking photos if half of them disappear? exactly, there’s none.

face-api returns nothing when it can’t find a face, and i was quietly dropping those photos. drop a landscape or a logo and it just vanished from the results. now every photo gets a card. no face means it says “no face detected” and sinks to the bottom. nothing disappears anymore.


The Ring Thing

the old upload screen was a plain button. boring. the new one is your photos, cropped into circles, orbiting in concentric rings on a tilted plane with a citrus glow behind them, the rank button sitting dead center.


What I Learned

here’s the problem nobody warns you about. if you spin a ring, everything pinned to it spins too. so your face would slowly tumble upside down as it goes around. not a good look.

the fix is a counter-spin. the photo sits inside a wrapper that rotates the opposite direction at the exact same speed as its ring. the two cancel out. the ring carries the photo around the circle, the wrapper holds the face perfectly level the entire way.

i also learned the hard way that your local dev server lies to you. i had a busted line of css, var(var(–accent-soft)), sitting in the code for days. local never said a word. the second Vercel ran the real production build, it rejected it instantly and killed the whole deploy. one line. fixed it, pushed again, live.


Tip of the Day

shoot at eye level, not from below.

a low angle points the lens up your nose and widens your jaw. eye level flatters basically everyone. bonus, the app rewards it too, since a centered well-framed face scores higher until next time, -ziyaad :) (please lmk any feedback)

0

Loading discussion…

0
1
Open comments for this post

1h 23m 59s logged


PFP Studio Devlog #2

the scoring system is done.

four checks per photo: centering, size, brightness, sharpness. each one reads the actual pixel data from the face region and turns it into a number. combine them with weights, sort the results, and the best photo rises to the top.

the sharpness one was the most interesting to build. it loops through every pixel and compares it to the pixels directly to its right and below. blurry photos have smooth transitions. sharp photos have high contrast between neighbors. the bigger the average difference, the sharper the photo.


the ui got a full revamp too.

went from raw unstyled html to something that actually looks like a product. warm cream background, Syne for the headings, orange accent for the winner card. each result staggered in with a fade. the #1 card gets an orange ring and shows the “why it won” explanation underneath.


it works.

uploaded 5 photos, hit rank, and the results actually make sense. the best-lit, well-centered shot came out on top. the blurry one ranked last.


what’s next: loading states so it doesn’t feel frozen while processing, and filling out the empty state so the page doesn’t look bare on load.

then it ships.


0

Loading discussion…

0
13
Open comments for this post

1h 10m 40s logged

PFP Studio Devlog #1.5

ok so here’s the thing.

everyone has that moment where they’re picking a profile pic and they just… can’t decide. you’re staring at 12 photos that all look basically the same and you pick one based on vibes.

i wanted to fix that.

the idea is simple. upload your photos, the app checks each face, scores them on actual stuff (is it centered, is the face big enough, is it well lit, is it sharp or blurry), then ranks them. #1 wins. done.


getting started was rougher than expected

i’d used html/css/js before but this was my first real React project. spent an embarrassing amount of time confused about why my component wasn’t showing up before realizing i named it uploadZone instead of UploadZone. React treats lowercase as HTML tags. learned that one the hard way.

also had a white screen moment that lasted way longer than i want to admit. turned out export default App was just… missing. one line.


the model files situation

face-api.js needs ML model files to detect faces. downloaded them through the browser. seemed fine. then got this error: “tensor should have 864 values but has 617.”

turns out the browser saved them as HTML files instead of the actual binary. re-downloaded them properly, everything worked.


where it’s at now

the core scoring works. it reads pixel data from each face region, runs four checks, combines them into a total score, and sorts the photos. tested it and the ranking actually makes sense.

next: working on the logic and reasoning behind the best pfp and then later making the app look nice :)

we’ll see how that goes.

-Ziyaad

0

Loading discussion…

0
1

Followers

Loading…