Generate a professional portrait, upscale it, create a website banner, and animate a subtle intro video.
Personal Website Hero Assets
Use this workflow for founder profiles, portfolio sites, speaker pages, or a polished about page. It turns a trained identity model into a portrait, a wider first-viewport banner, and a restrained intro video.
Before you start
Complete Setup and Training first. These snippets assume
modelId or model_id, triggerImageGeneration, triggerImageUpscaling,
triggerVideoGeneration, waitForJob, and firstImage are already available.
Workflow
- Generate a clean hero portrait with
POST /images/generation. - Upscale the selected portrait with
POST /images/upscaling. - Create a wide website banner with
POST /images/generation. - Animate the banner with
POST /videos/generation.
Generate a clean hero portrait
The trained model gives you consistent identity across website images.
const heroImageJobId = await triggerImageGeneration({
modelID: modelId,
prompt:
'confident personal website hero portrait, clean studio background, modern professional lighting',
width: 1024,
height: 1024,
numImages: 2,
enhanceFace: true,
})
const heroImage = firstImage(await waitForJob(heroImageJobId), 'Website hero portrait')hero_image_job_id = trigger_image_generation(
{
"modelID": model_id,
"prompt": "confident personal website hero portrait, clean studio background, modern professional lighting",
"width": 1024,
"height": 1024,
"numImages": 2,
"enhanceFace": True,
}
)
hero_image = first_image(wait_for_job(hero_image_job_id), "Website hero portrait")Upscale the hero portrait
Upscale the selected hero portrait so the website banner generation has a sharper reference.
const heroUpscaleJobId = await triggerImageUpscaling({
imageID: heroImage.id,
})
const heroUpscaledImage = firstImage(await waitForJob(heroUpscaleJobId), 'Website hero upscale')hero_upscale_job_id = trigger_image_upscaling(
{
"imageID": hero_image["id"],
}
)
hero_upscaled_image = first_image(
wait_for_job(hero_upscale_job_id),
"Website hero upscale",
)Create a wide website banner
Use the upscaled portrait as reference and generate a wider image that works in a first viewport or social preview.
const heroBannerJobId = await triggerImageGeneration({
modelID: 'gpt-image-2',
prompt:
'editorial website hero image, confident founder portrait, laptop and notebook on desk, refined modern brand style',
aspectRatio: '16:9',
numImages: 1,
referenceImageURLs: [heroUpscaledImage.url],
options: {
openai: {
imageSize: '1K',
outputFormat: 'jpeg',
quality: 'high',
},
},
})
const heroBanner = firstImage(await waitForJob(heroBannerJobId), 'Website hero banner')hero_banner_job_id = trigger_image_generation(
{
"modelID": "gpt-image-2",
"prompt": "editorial website hero image, confident founder portrait, laptop and notebook on desk, refined modern brand style",
"aspectRatio": "16:9",
"numImages": 1,
"referenceImageURLs": [hero_upscaled_image["url"]],
"options": {
"openai": {
"imageSize": "1K",
"outputFormat": "jpeg",
"quality": "high",
},
},
}
)
hero_banner = first_image(wait_for_job(hero_banner_job_id), "Website hero banner")Generate a subtle intro video
Use the banner as the first frame and keep motion restrained for a professional website.
const heroVideoJobId = await triggerVideoGeneration({
modelID: 'seedance-2.0',
prompt:
'personal website intro video, founder looks toward camera, slight push-in camera movement, professional and approachable',
numVideos: 1,
referenceImages: [
{
url: heroBanner.url,
role: 'first_frame',
},
],
options: {
seedance: {
duration: 6,
ratio: '16:9',
resolution: '1080p',
generateAudio: false,
},
},
})
const heroVideoJob = await waitForJob(heroVideoJobId, 8000)
const heroVideo = heroVideoJob.videos?.[0]hero_video_job_id = trigger_video_generation(
{
"modelID": "seedance-2.0",
"prompt": "personal website intro video, founder looks toward camera, slight push-in camera movement, professional and approachable",
"numVideos": 1,
"referenceImages": [
{
"url": hero_banner["url"],
"role": "first_frame",
},
],
"options": {
"seedance": {
"duration": 6,
"ratio": "16:9",
"resolution": "1080p",
"generateAudio": False,
},
},
}
)
hero_video_job = wait_for_job(hero_video_job_id, interval_seconds=8)
hero_video = hero_video_job.get("videos", [])[0]Production notes
- Keep this workflow visually restrained: simple background, clean lighting, minimal motion.
- Use
16:9for first-viewport banners and social previews. - Use the final banner as the video first frame so the page and video share a consistent opening visual.