File size: 2,129 Bytes
7204a8e
fed2ac4
7204a8e
 
 
 
 
 
 
 
fed2ac4
 
 
 
 
 
7204a8e
ed02105
 
7204a8e
 
 
 
ed02105
7204a8e
ed02105
80f9e6d
 
 
 
7204a8e
80f9e6d
 
 
7204a8e
80f9e6d
7204a8e
ea3e859
 
 
80f9e6d
ea3e859
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
80f9e6d
ea3e859
80f9e6d
 
 
 
9fab985
f052b27
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
from fastapi import FastAPI, File, UploadFile
from fastapi.responses import Response, JSONResponse
from insightface.app import FaceAnalysis
from rembg import remove
from PIL import Image
import numpy as np
import io

app = FastAPI()

# Simple homepage (fixes 404 on HF Spaces)
@app.get("/")
def home():
    return {"message": "ID Photo API is running. Use POST /process"}

# Load face detection model
face_app = FaceAnalysis(name="buffalo_l", providers=["CPUExecutionProvider"])
face_app.prepare(ctx_id=0, det_size=(640, 640))


def resize_to_4x6(img):
    return img.resize((472, 709), Image.LANCZOS)


@app.post("/process")
async def process_img(file: UploadFile = File(...)):
    try:
        img_bytes = await file.read()
        img = Image.open(io.BytesIO(img_bytes)).convert("RGB")
        np_img = np.array(img)

        faces = face_app.get(np_img)
        if not faces:
            return JSONResponse({"error": "No face detected"}, status_code=400)

        face = faces[0]

        # --- Extract face bounding box ---
        x1, y1, x2, y2 = face.bbox.astype(int)
        cropped = img.crop((x1, y1, x2, y2))

        # --- Resize cropped face with preserved aspect ratio ---
        max_face_height = int(709 * 0.75)  # face occupies 75% of final height
        w, h = cropped.size
        scale_factor = max_face_height / h

        new_w = int(w * scale_factor)
        new_h = int(h * scale_factor)
        resized_face = cropped.resize((new_w, new_h), Image.LANCZOS)

        # --- Create final white 4x6 canvas ---
        final_w, final_h = 472, 709
        canvas = Image.new("RGB", (final_w, final_h), (255, 255, 255))

        # --- Center image on canvas ---
        paste_x = (final_w - new_w) // 2
        paste_y = (final_h - new_h) // 2
        canvas.paste(resized_face, (paste_x, paste_y))

        # --- Output final image ---
        buf = io.BytesIO()
        canvas.save(buf, format="JPEG")
        buf.seek(0)
        return Response(buf.getvalue(), media_type="image/jpeg")

    except Exception as e:
        print("ERROR:", e)
        return JSONResponse({"error": str(e)}, status_code=500)