| name | crop-and-resize |
| description | Use when the user wants ID-style 3×4 photos, an A4 print sheet of faces, or batch resizing of images for printing. Triggers on "fotos 3x4", "passport photo", "ID photo", "tile faces on A4", "resize for print". |
crop-and-resize
End-to-end workflow for face-aware ID-photo cropping and A4 tiling. Repo-local skill — assumes image-playground layout.
When to use
Pick this skill if the user wants any of:
- Crop one or more faces from photos into 3×4 cm format
- Build an A4 print sheet of faces (with multiple copies, or one of each)
- Batch resize images to a fixed square size for printing
Inputs
The user typically provides:
- Source photos — already in
samples/, or paths/URLs to copy in.
- Selection — which detected faces to keep (numbered after first run).
- Layout choice — fill the sheet with copies, or place one of each.
- Spacing — gap between photos (default 0.5 cm).
Workflow
digraph crop_resize_flow {
"Receive request" [shape=doublecircle];
"Source images in samples/?" [shape=diamond];
"Copy/download to samples/" [shape=box];
"Run script (no flags)" [shape=box];
"Show contact_sheet.jpg" [shape=box];
"User confirms which faces to keep" [shape=box];
"Run with --keep=... [--unique]" [shape=box];
"Show a4_sheet.jpg" [shape=box];
"Adjust spacing/layout?" [shape=diamond];
"Edit SPACING_CM, re-run" [shape=box];
"Done" [shape=doublecircle];
"Receive request" -> "Source images in samples/?";
"Source images in samples/?" -> "Run script (no flags)" [label="yes"];
"Source images in samples/?" -> "Copy/download to samples/" [label="no"];
"Copy/download to samples/" -> "Run script (no flags)";
"Run script (no flags)" -> "Show contact_sheet.jpg";
"Show contact_sheet.jpg" -> "User confirms which faces to keep";
"User confirms which faces to keep" -> "Run with --keep=... [--unique]";
"Run with --keep=... [--unique]" -> "Show a4_sheet.jpg";
"Show a4_sheet.jpg" -> "Adjust spacing/layout?";
"Adjust spacing/layout?" -> "Edit SPACING_CM, re-run" [label="yes"];
"Adjust spacing/layout?" -> "Done" [label="no"];
"Edit SPACING_CM, re-run" -> "Show a4_sheet.jpg";
}
Step-by-step
1. Verify the venv
[ -d .venv ] || python3 -m venv .venv
.venv/bin/pip install -q -r requirements.txt
2. First pass — detect all faces
.venv/bin/python scripts/face_to_a4.py
Produces:
output/individual_crops/face_NN.jpg — every detected face cropped to 3×4
output/contact_sheet.jpg — numbered preview, show this to the user
output/a4_sheet.jpg — first-pass A4 with all faces tiled
3. Show the contact sheet
Read output/contact_sheet.jpg and let the user identify which numbered faces to keep (duplicates across photos, false positives at edges, bystanders).
4. Rebuild with selection
.venv/bin/python scripts/face_to_a4.py --keep=1,3,5,7
Each kept face is tiled to fill the A4 (copies distributed evenly).
For literal one-of-each (no duplicates, mostly empty sheet):
.venv/bin/python scripts/face_to_a4.py --keep=1,3,5,7 --unique
5. Spacing and tunables
Top of scripts/face_to_a4.py:
| Constant | Default | Meaning |
|---|
DPI | 300 | Print resolution |
PHOTO_CM | (3, 4) | Crop size (width, height) in cm |
A4_CM | (21, 29.7) | Sheet size |
SPACING_CM | 0.5 | Gap between cells (cut-line) |
MIN_FACE_PX | 130 | Reject smaller detections (background) |
Edit in place and re-run; no flags for these (intentional — change is rare).
6. Batch resize (alternative path)
If the user just wants square crops for printing (no face detection):
./scripts/resize.sh -s 8 -u cm samples/*.jpg
./scripts/resize.sh -s 4 -u inch -o output/ *.jpg
./scripts/resize.sh -h
Common pitfalls
- Multiple detections of one person across photos. The script can't dedupe by identity (no
face_recognition). Always show the contact sheet and let the user pick.
- Tight crops cutting off hair. Tune
photo_h = fh * 1.7 in crop_3x4() upward (e.g., 1.9) for more headroom.
- Bystanders detected. Raise
MIN_FACE_PX from 130 to 180+ to drop background faces.
- Dropped a personal photo into
samples/. Move it elsewhere — samples/ is committed to git. Use output/ for anything ephemeral.