import React, { useState, useRef, useEffect } from 'react'; import { Camera, RefreshCcw } from 'lucide-react'; export default function FaceShapeAnalyzer() { const [stream, setStream] = useState(null); const [imageCapture, setImageCapture] = useState(null); const [analysis, setAnalysis] = useState(null); const [isAnalyzing, setIsAnalyzing] = useState(false); const videoRef = useRef(null); const canvasRef = useRef(null); const faceShapes = { oval: { description: "Oval face shape is considered the most balanced.", hairstyles: [ "Medium-length cuts with layers", "Long, flowing waves", "Virtually any hairstyle works well" ] }, round: { description: "Round face shape has soft angles and similar length and width.", hairstyles: [ "Long layers with side-swept bangs", "Asymmetrical cuts", "Volume at the crown" ] }, square: { description: "Square face shape has strong jaw and angular features.", hairstyles: [ "Soft layers around the face", "Side-swept styles", "Textured, wispy cuts" ] }, heart: { description: "Heart face shape is wider at forehead and narrower at chin.", hairstyles: [ "Side-parted styles", "Chin-length bobs", "Long layers with side bangs" ] }, diamond: { description: "Diamond face shape has narrow forehead and jawline with wide cheekbones.", hairstyles: [ "Side-swept bangs", "Chin-length or longer styles", "Layered cuts that add width at the jawline" ] }, rectangular: { description: "Rectangular face shape is longer than it is wide with angular features.", hairstyles: [ "Side-swept bangs", "Layered cuts with volume", "Medium-length styles with waves" ] } }; useEffect(() => { startCamera(); return () => { if (stream) { stream.getTracks().forEach(track => track.stop()); } }; }, []); const startCamera = async () => { try { const mediaStream = await navigator.mediaDevices.getUserMedia({ video: { facingMode: 'user', width: { ideal: 1280 }, height: { ideal: 720 } } }); setStream(mediaStream); if (videoRef.current) { videoRef.current.srcObject = mediaStream; const track = mediaStream.getVideoTracks()[0]; setImageCapture(new ImageCapture(track)); } } catch (error) { console.error('Error accessing camera:', error); } }; const analyzeFace = async () => { if (!imageCapture) return; setIsAnalyzing(true); try { const bitmap = await imageCapture.grabFrame(); const canvas = canvasRef.current; const context = canvas.getContext('2d'); canvas.width = bitmap.width; canvas.height = bitmap.height; context.drawImage(bitmap, 0, 0); // Convert canvas to base64 (smaller size) const imageData = canvas.toDataURL('image/jpeg', 0.5); // Prepare the messages for AI analysis const messages = [ { role: "system", content: `You are an expert facial analysis AI. Analyze the face shape in the image and respond with ONLY ONE of these face shapes: oval, round, square, heart, diamond, or rectangular. Do not include any other text in your response.` }, { role: "user", content: `What is the face shape in this image: ${imageData}` } ]; try { const response = await fetch('https://www.sitebrew.ai/api/genai', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ messages }) }); if (!response.ok) { throw new Error('Failed to get AI response'); } const data = await response.json(); console.log('AI Response:', data); // For debugging let faceShape = data.message.content.toLowerCase().trim(); // Clean up the response to match our face shapes faceShape = faceShape.replace(/^(i see a|i think it's a|this is a|appears to be|looks like a) /, ''); faceShape = faceShape.replace(/\W+/g, ''); if (!faceShapes[faceShape]) { faceShape = 'oval'; // Default to oval if we get an invalid response } setAnalysis({ faceShape, ...faceShapes[faceShape] }); } catch (error) { console.error('AI Analysis error:', error); alert('There was an error analyzing your face shape. Please try again.'); } } catch (error) { console.error('Camera capture error:', error); alert('There was an error capturing the image. Please make sure you have good lighting and are facing the camera.'); } finally { setIsAnalyzing(false); } }; return (

Face Shape Analyzer

Discover your face shape and get personalized hairstyle recommendations

Please ensure:

  • • Your face is well-lit
  • • You're facing the camera directly
  • • Your entire face is visible
{analysis && (

Your Results

Face Shape: {analysis.faceShape.charAt(0).toUpperCase() + analysis.faceShape.slice(1)}

{analysis.description}

Recommended Hairstyles:

    {analysis.hairstyles.map((style, index) => (
  • {style}
  • ))}
)}
); }