PluginBench
Skill
Pass
Audit score 90

image-portrait

starchild-ai-agent/official-skills

How to install image-portrait

npx skills add https://github.com/starchild-ai-agent/official-skills --skill image-portrait
Claude Code
Cursor
Windsurf
Cline
Full instructions (SKILL.md)

Source of truth, from starchild-ai-agent/official-skills.


name: image-portrait version: 1.0.1 description: | Identity-consistent portrait generation from a reference photo. Covers professional headshots, dating photos, style transfers, themed portraits, photo series, avatars, ID photos.

Use when generating styled portraits from a reference photo (e.g. professional headshot, anime avatar, cyberpunk portrait, travel photo, dating profile photo, ID photo). metadata: starchild: emoji: "๐Ÿ“ธ" skillKey: image-portrait requires: env: [FAL_KEY] user-invocable: true disable-model-invocation: false


image-portrait

Use this skill for all identity-consistent portrait generation requests on Starchild.

Covers: professional headshots, dating/social photos, artistic style transfers, themed/holiday portraits, photo series, digital avatars, children/family photos, ID/passport photos.

Core principle: call the provided script. Do not re-implement proxy/billing plumbing.


1. Quick start โ€” single portrait (most common)

exec(open('skills/image-portrait/generate_portrait.py').read())
result = generate_portrait(
    image_path="path/to/user/photo.jpg",
    style="professional",
)
# result -> {"success": True, "images": [{"local_path": "output/images/..."}], ...}

The script reads the local file, base64-encodes it, and sends it to fal.ai as a data URI โ€” no manual URL publishing needed.

2. Quick start โ€” public URL

exec(open('skills/image-portrait/generate_portrait.py').read())
result = generate_portrait(
    face_image_url="https://example.com/photo.jpg",
    style="anime",
)

3. Quick start โ€” text-to-image (no reference photo)

exec(open('skills/image-portrait/generate_portrait.py').read())
result = generate_portrait(
    prompt="a young woman in cyberpunk armor, neon city background, rain",
    model="nanopro",
)

When no image_path or face_image_url is provided, the script uses the text-to-image endpoint (no /edit suffix).

Delivering the result to the user โ€” IMPORTANT

Never hand the user the raw fal.media URL. fal serves files with restrictive CSP headers. The only reliable delivery path is the already-downloaded local file:

  1. Use each image's local_path (e.g. output/images/xxx.png) โ€” the script always downloads on success.
  2. Tell the user the files are saved to output/images/ and viewable in the workspace file panel.
  3. On Web channel, embed inline so the user can preview in chat:
    ![photo](output/images/<filename>.png)
    
  4. On Telegram / WeChat: send via send_to_telegram(file_path="output/images/...", message_type="image") or send_to_wechat(file_path="output/images/...", message_type="image").

4. Parameters

ParameterRequiredDefaultDescription
image_pathnoโ€”Local workspace file path to the user's face photo
face_image_urlnoโ€”Public HTTPS URL of the user's face photo
styleno"professional"Preset style key (see ยง5)
scenenoNoneCustom scene description (appended to style prompt)
promptnoNoneFully custom prompt โ€” overrides style+scene when set
modelno"nanopro"Model: "nano2" (fastest ~15s), "nanopro" (balanced ~25s, default), or "gpt" (best quality ~150s)
countno1Number of images to generate (1โ€“8)
aspect_rationo"1:1"Output ratio: 1:1, 3:4, 4:3, 9:16, 16:9

Image input rules:

  • Provide image_path OR face_image_url for identity-consistent generation (edit mode).
  • If both are given, image_path takes priority.
  • Omit both for pure text-to-image generation (generate mode).

Prompt priority: prompt > style + scene > style > default (professional).


5. Style presets

A: Identity-consistent character styles

StyleKeyBest for
Professional headshotprofessionalLinkedIn, resume, corporate
Artistic portraitartisticCreative portfolio, gallery
AnimeanimeSocial media, fun avatar
CyberpunkcyberpunkGaming profile, sci-fi fan
Oil paintingoil_paintingArt gift, classical look
WatercolorwatercolorSoft artistic portrait
VintagevintageRetro aesthetic, nostalgia
Casual lifestylecasualSocial media, personal blog

B: Personal showcase / dating / social

StyleKeyBest for
Dating โ€” cafedating_cafeDating app, warm vibe
Dating โ€” beachdating_beachDating app, summer vibe
Dating โ€” citydating_cityDating app, urban vibe
Dating โ€” restaurantdating_restaurantDating app, elegant vibe
Travel โ€” Europetravel_europeTravel blog, social media
Travel โ€” Japantravel_japanTravel blog, cultural
Travel โ€” tropicaltravel_tropicalVacation, resort
Sports โ€” gymsports_gymFitness profile
Sports โ€” runningsports_runningAthletic profile
Social mediasocial_mediaInstagram, TikTok
LinkedInlinkedinProfessional networking
Personal brandpersonal_brandEntrepreneur, creator

D: Themed / scene portraits

StyleKeyBest for
ChristmaschristmasHoliday greeting, social
HalloweenhalloweenHoliday fun
GraduationgraduationMilestone celebration
WeddingweddingWedding planning, save-the-date
Business speechbusiness_speechSpeaker profile
MusicianmusicianMusic promotion
ChefchefFood blog, restaurant
Outdoor adventureoutdoor_adventureAdventure blog
Pet togetherpet_togetherPet lover profile
ReadingreadingBook club, literary
Night citynight_cityUrban lifestyle
Hanfu (Chinese traditional)hanfuCultural, cosplay

O: Digital avatar

StyleKeyBest for
3D cartoonavatar_3dSocial avatar, Pixar style
Gaming avataravatar_gamingGame profile, RPG
VTuberavatar_vtuberStreaming, VTuber

T: Children & family

StyleKeyBest for
Child portraitchild_portraitFamily keepsake
Family photofamily_photoFamily portrait

U: ID / passport photos

StyleKeyBest for
ID photo (white bg)id_photo_whitePassport, driver's license
ID photo (blue bg)id_photo_blueVisa, work permit

6. Model selection guide

ModelKeySpeedQualityBest for
Nano Banana 2nano2~15sGoodQuick drafts, fast iteration, bulk generation.
NanoPronanopro~25sBetterDefault for all requests. Balanced speed and quality.
GPT Image 2gpt~150sBestWhen user explicitly asks for "highest quality" or "best quality". Complex scenes.

Decision rules:

  1. Default: always use nanopro unless the user explicitly requests otherwise.
  2. Use nano2 when: user wants fastest results, is iterating on styles, generating many images, or says "quick", "draft", "fast".
  3. Use gpt when: user says "highest quality", "best quality", "premium", or the scene is very complex with many specific details.
# Default (fast)
result = generate_portrait(image_path="photo.jpg", style="anime")

# High quality (user requested)
result = generate_portrait(image_path="photo.jpg", style="anime", model="gpt")

7. Custom scene examples

# Style + custom scene
result = generate_portrait(
    image_path="uploads/my_photo.jpg",
    style="professional",
    scene="in a modern office with city skyline view",
)

# Custom scene only (defaults to professional style base)
result = generate_portrait(
    image_path="uploads/my_photo.jpg",
    scene="standing on a beach at sunset, golden hour lighting",
)

# Fully custom prompt (overrides everything)
result = generate_portrait(
    image_path="uploads/my_photo.jpg",
    prompt="portrait of a person as a medieval knight, full plate armor, castle background, dramatic lighting, oil painting style",
)

# Different aspect ratio
result = generate_portrait(
    image_path="uploads/my_photo.jpg",
    style="cyberpunk",
    aspect_ratio="9:16",
)

# Multiple images
result = generate_portrait(
    image_path="uploads/my_photo.jpg",
    style="dating_cafe",
    count=4,
)

8. Prompt engineering best practices

When the user's request doesn't match any preset style, or when you need to construct a custom prompt, follow these guidelines (derived from reference skills: ai-headshot-generation, ai-avatar-generation, style-transfer, portrait-enhancement, character-design-sheet, avatar-portrait, nano-banana-pro, pet-portrait-generation).

Automatic likeness preservation

When a reference image is provided (edit mode), the script automatically prepends a likeness preservation instruction to every prompt. This ensures the generated portrait preserves the subject's facial identity. You do NOT need to add likeness instructions manually โ€” the script handles it.

Exception: avatar styles (avatar_3d, avatar_gaming, avatar_vtuber) skip the likeness prefix because stylization takes priority over photographic likeness.

The 7-element prompt structure

Every effective portrait prompt should include these elements (from nano-banana-pro skill):

[subject], [outfit/attire], [pose/action], [expression], [background/setting], [lighting], [style/quality modifiers]

Key principles

  1. Likeness vs. style balance (from avatar-portrait skill):

    • Too photorealistic = ignores requested style
    • Too stylized = loses resemblance to source person
    • For stylized portraits: emphasize "stylized but maintains individual features"
    • For photorealistic: emphasize "keep facial features recognizable"
  2. Lighting is critical โ€” always specify lighting type:

    • Studio: "soft diffused studio lighting", "Rembrandt chiaroscuro lighting"
    • Natural: "golden hour warm light", "dappled sunlight through trees"
    • Dramatic: "dramatic rim lighting", "volumetric light beams", "neon glow"
    • Flat: "even flat lighting with no shadows" (for ID photos)
  3. Background specificity โ€” vague backgrounds produce poor results:

    • โŒ "nice background"
    • โœ… "blurred modern office with glass windows and city view"
    • โœ… "clean neutral gray gradient studio background"
    • โœ… "background style should match the character style" (for avatars)
  4. Lens/camera hints โ€” help the model understand framing:

    • "85mm lens look, shallow depth of field" (portrait)
    • "head and shoulders framing" (headshot)
    • "full body, clean white background" (character design)
    • "close-up face, portrait orientation" (expression/avatar)
  5. Quality anchors โ€” add style quality references:

    • "professional photography quality", "magazine cover quality"
    • "National Geographic photography style" (adventure)
    • "League of Legends splash art style" (gaming)
    • "Pixar and Disney animation style" (3D avatar)
    • "Studio Ghibli inspired" (anime)
    • "fine art watercolor painting look" (watercolor)
  6. Texture and material โ€” for artistic styles, specify medium:

    • "visible impasto brushstrokes, canvas texture" (oil painting)
    • "loose expressive watercolor style, soft edges, beautiful color bleeds and washes" (watercolor)
    • "natural film grain, Kodak Portra emulation" (vintage)
    • "cel-shaded, clean line art, bold outlines" (anime)
    • "visible pixels but NOT a pixelated photo filter" (pixel art)
  7. Expression guidance โ€” be specific about mood:

    • โŒ "smiling"
    • โœ… "warm genuine smile, confident approachable expression"
    • โœ… "neutral calm expression with mouth closed" (ID photo)
    • โœ… "passionate expression, energetic" (musician)

Example: building a custom prompt

User: "I want a photo of me as a wizard in a magical forest"

result = generate_portrait(
    image_path="uploads/photo.jpg",
    prompt=(
        "fantasy wizard portrait, wearing mystical purple robes with glowing runes, "
        "ancient wooden staff with crystal orb, wise powerful expression, "
        "enchanted forest background with bioluminescent plants and floating particles, "
        "dramatic magical lighting with ethereal glow, "
        "high fantasy art style, detailed digital painting quality"
    ),
)
# Note: likeness prefix is auto-added because image_path is provided

Example: pixel art avatar (from avatar-portrait skill)

User: "Make me a retro pixel art avatar"

result = generate_portrait(
    image_path="uploads/photo.jpg",
    prompt=(
        "retro 16-bit pixel art portrait, visible pixels with clean lines, "
        "rich colors, consistent shading, stylized but maintains individual features, "
        "warm sunset cityscape background in matching pixel art style, "
        "head and shoulders, square format"
    ),
)

9. Photo series

Generate a coordinated set of themed portraits in one call. Pass a custom list of styles/scenes โ€” the agent assembles the list based on the user's request.

exec(open('skills/image-portrait/generate_portrait.py').read())
result = generate_series(
    image_path="uploads/my_photo.jpg",
    series=[
        {"style": "professional"},
        {"style": "casual", "scene": "at a rooftop bar, sunset"},
        {"style": "anime"},
        {"prompt": "portrait as a superhero, cape flowing, city skyline"},
    ],
)
# result -> {"success": True, "images": [...4 images...], "series": "custom"}

Each item in the list is a dict with optional keys:

  • style โ€” any style key from ยง7 (e.g. "professional", "anime", "cyberpunk")
  • scene โ€” override the scene description (combined with the style template)
  • prompt โ€” fully custom prompt (ignores style/scene)

10. Intent recognition guide

Use this table to map user requests to the correct style/parameters:

User saysStyleNotes
"professional photo", "headshot", "LinkedIn photo"professional or linkedin
"dating photo", "dating app", "Tinder photo"dating_cafe / dating_beach / dating_cityAsk which vibe
"anime me", "anime version", "cartoon me"anime
"cyberpunk", "sci-fi portrait"cyberpunk
"oil painting", "classical portrait"oil_painting
"watercolor portrait"watercolor
"vintage photo", "retro"vintage
"casual photo", "lifestyle"casual
"travel photo in Paris/Europe"travel_europe
"travel photo in Japan/Tokyo/Kyoto"travel_japan
"beach photo", "tropical"travel_tropical or dating_beach
"gym photo", "fitness"sports_gym
"Christmas photo"christmas
"Halloween photo"halloween
"graduation photo"graduation
"wedding photo"wedding
"chef photo", "cooking"chef
"musician", "on stage"musician
"with my dog/pet"pet_together
"reading", "bookish"reading
"night city", "urban night"night_city
"hanfu", "Chinese traditional"hanfu
"3D avatar", "Pixar style"avatar_3d
"gaming avatar", "RPG character"avatar_gaming
"VTuber avatar"avatar_vtuber
"kid photo", "children's portrait"child_portrait
"family photo"family_photo
"passport photo", "ID photo"id_photo_whiteWhite bg default
"visa photo"id_photo_blueBlue bg
"photo series", "set of photos"Use generate_series()Assemble custom list from styles
"highest quality", "best quality"Any style + model="gpt"
Custom scene not in presetsUse scene= or prompt=

11. Provided scripts

FilePurpose
generate_portrait.pyCore script: submit โ†’ poll โ†’ download. Handles local files (base64) and URLs, all styles, custom scenes, three models (nano2/nanopro/gpt).
exports.pyRe-exports generate_portrait, generate_series, STYLE_PROMPTS for programmatic use by other skills.
_cost_track.pyCost tracking helper โ€” records per-call costs via sc-proxy headers.

12. Local testing

Set FAL_KEY env var to call fal.ai directly (bypasses sc-proxy):

# Single portrait
FAL_KEY=your-fal-key python3 skills/image-portrait/generate_portrait.py photo.jpg anime 1 nanopro

# Args: <image_path_or_url> [style] [count] [model]

13. Troubleshooting

ProblemFix
File not found: ...Check the workspace path; the file must exist
Unsupported image formatUse .jpg, .jpeg, .png, .webp, or .bmp
Image too largeResize to under 10 MB before uploading
face_image_url must be a public HTTP(S) URLUse image_path for local files, or provide a valid https:// URL
HTTP 402 insufficient_creditsTop up balance; cost is pre-charged on submit
HTTP 403 endpoint_not_allowedsc-proxy only allows approved fal endpoints; contact admin
Generation FAILED upstreamSimplify prompt, ensure face photo is clear and well-lit, retry
Job stuck IN_PROGRESS >10 minSave request_id, retry later
Poor face consistencyUse a clear, front-facing photo with good lighting; avoid group photos
gpt model too slowSwitch to nanopro (default) for faster results

14. Infrastructure (reference)

  • Caller โ†’ sc-proxy โ†’ queue.fal.run/{model} โ†’ fal model providers
  • All requests must include Authorization: Key fake-falai-key-12345 (proxy injects the real FAL_KEY)
  • Pre-charge happens at submit. Poll/result calls are free.
  • Local files are base64-encoded as data URIs โ€” no separate upload step needed.
  • Final images live at https://*.fal.media/... โ€” public CDN, no auth needed for download.
  • Cost tracking via _cost_track.py โ€” records X-Credits-Used from sc-proxy response headers.

Model endpoints

ModelEdit (with ref image)Generate (text only)
nano2fal-ai/nano-banana-2/editfal-ai/nano-banana-2
nanoprofal-ai/nano-banana-pro/editfal-ai/nano-banana-pro
gptopenai/gpt-image-2/editopenai/gpt-image-2