This workflow corresponds to n8n.io template #12645 — we link there as the canonical source.
This workflow follows the Agent → Form Trigger recipe pattern — see all workflows that pair these two integrations.
The workflow JSON
Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →
{
"id": "dp5oMxNtiDV7ZQwO",
"name": "\ud83d\udca5 Create scalable e-commerce product images using NanoBanana Pro",
"tags": [],
"nodes": [
{
"id": "d32f2efc-96d4-460c-acca-3d4271e96be3",
"name": "Form Trigger (3 images)",
"type": "n8n-nodes-base.formTrigger",
"position": [
-624,
-320
],
"parameters": {
"options": {
"buttonLabel": "Analyze Images"
},
"formTitle": "Upload 3 Images for Analysis ",
"formFields": {
"values": [
{
"fieldName": "image1",
"fieldType": "file",
"fieldLabel": "Image 1",
"multipleFiles": false,
"requiredField": true,
"acceptFileTypes": ".jpg, .jpeg, .png, .gif, .bmp, .webp"
},
{
"fieldName": "Image2",
"fieldType": "file",
"fieldLabel": "Image 2",
"multipleFiles": false,
"requiredField": true,
"acceptFileTypes": ".jpg, .jpeg, .png, .gif, .bmp, .webp"
},
{
"fieldName": "Image3",
"fieldType": "file",
"fieldLabel": "Image 3",
"multipleFiles": false,
"requiredField": true,
"acceptFileTypes": ".jpg, .jpeg, .png, .gif, .bmp, .webp"
},
{
"fieldName": "notes",
"fieldLabel": "Optional Notes"
}
]
},
"formDescription": "Please upload exactly 3 images for AI-powered analysis"
},
"typeVersion": 2.4
},
{
"id": "b52765ea-f694-4a3d-9047-db35528a5a28",
"name": "If",
"type": "n8n-nodes-base.if",
"position": [
-384,
-320
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 3,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "loose"
},
"combinator": "and",
"conditions": [
{
"id": "330c555d-c5d5-4e14-af52-1d45ed2ac896",
"operator": {
"type": "boolean",
"operation": "exists",
"singleValue": true
},
"leftValue": "={{ $binary.image1 }}",
"rightValue": ""
},
{
"id": "975e8e54-27fb-4513-ac45-d719ad1157b0",
"operator": {
"type": "boolean",
"operation": "exists",
"singleValue": true
},
"leftValue": "={{ $binary.Image2 }}",
"rightValue": ""
},
{
"id": "02ec63f3-9dd8-4db1-986e-69cac26e245d",
"operator": {
"type": "boolean",
"operation": "exists",
"singleValue": true
},
"leftValue": "={{ $binary.Image3 }}",
"rightValue": ""
}
]
},
"looseTypeValidation": true
},
"typeVersion": 2.3
},
{
"id": "5fc9d593-7d41-4a7e-a77c-a0ce436600f2",
"name": "Error Response - Missing Files",
"type": "n8n-nodes-base.set",
"position": [
-144,
-64
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "20d99650-4a2f-41cc-be31-2f4d1f436712",
"name": "error",
"type": "string",
"value": "Please upload 3 images (image1, image2, image3)."
}
]
}
},
"typeVersion": 3.4
},
{
"id": "39315c75-3f8e-4fab-8b90-f6f2f565f27c",
"name": "Normalize binary names",
"type": "n8n-nodes-base.set",
"position": [
-144,
-336
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "065fa52e-70ee-4b41-8fa2-ad66ea218fe6",
"name": "image0",
"type": "object",
"value": "={{ $binary.image1 }}"
},
{
"id": "70b7494e-b43b-45ff-9da3-7b8e585b2a0d",
"name": "image1",
"type": "object",
"value": "={{ $binary.Image2 }}"
},
{
"id": "59862088-7957-4281-897b-9569d70a1c75",
"name": "image2",
"type": "object",
"value": "={{ $binary.Image3 }}"
}
]
},
"includeOtherFields": true
},
"typeVersion": 3.4
},
{
"id": "d3d728e3-e8a5-4247-b410-52dbd14527f7",
"name": "Split images",
"type": "n8n-nodes-base.code",
"position": [
64,
-336
],
"parameters": {
"jsCode": "const item = items[0];\n\nif (\n !item.binary ||\n !item.binary.image1 ||\n !item.binary.Image2 ||\n !item.binary.Image3\n) {\n throw new Error('Missing binary images (expected image1, image2, image3)');\n}\n\nreturn [\n {\n json: { imageNumber: 1 },\n binary: { image: item.binary.image1 }\n },\n {\n json: { imageNumber: 2 },\n binary: { image: item.binary.Image2 }\n },\n {\n json: { imageNumber: 3 },\n binary: { image: item.binary.Image3 }\n }\n];"
},
"typeVersion": 2
},
{
"id": "f44e2982-4e1e-4381-8057-b07c81d53bce",
"name": "Upload file",
"type": "n8n-nodes-base.googleDrive",
"position": [
304,
-576
],
"parameters": {
"name": "={{$binary.image.fileName}}",
"driveId": {
"__rl": true,
"mode": "id",
"value": "=<__PLACEHOLDER_VALUE__Google DRIVE Document ID___>"
},
"options": {},
"folderId": {
"__rl": true,
"mode": "id",
"value": "=<__PLACEHOLDER_VALUE__Google DRIVE Document ID___>"
},
"inputDataFieldName": "image"
},
"credentials": {
"googleDriveOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 3
},
{
"id": "4b785c13-f071-4a76-b925-d938fc4e81d2",
"name": "Analyze image",
"type": "@n8n/n8n-nodes-langchain.openAi",
"position": [
304,
-64
],
"parameters": {
"text": "Describe the image in detail. Include: objects, people, setting, actions, colors, and any text visible.",
"modelId": {
"__rl": true,
"mode": "list",
"value": "gpt-4o",
"cachedResultName": "GPT-4O"
},
"options": {},
"resource": "image",
"inputType": "base64",
"operation": "analyze",
"binaryPropertyName": "image"
},
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
},
"typeVersion": 2.1
},
{
"id": "25da78a8-5dc2-4084-93fe-a60c346da99f",
"name": "Merge",
"type": "n8n-nodes-base.merge",
"position": [
528,
-352
],
"parameters": {
"mode": "combine",
"options": {},
"combineBy": "combineByPosition",
"numberInputs": 3
},
"typeVersion": 3.2
},
{
"id": "e9c90cf0-e7fb-4819-978e-a21be8b4b54b",
"name": "Aggregate descriptions",
"type": "n8n-nodes-base.code",
"position": [
752,
-336
],
"parameters": {
"jsCode": "function extractOpenAIText(it) {\n // Apr\u00e8s Merge by position, OpenAI est sous la cl\u00e9 \"0\"\n const openai = it.json?.[\"0\"];\n\n if (openai?.content && Array.isArray(openai.content)) {\n const t = openai.content.map(x => x?.text).filter(Boolean).join(\"\\n\");\n if (t) return t;\n }\n\n // fallback\n if (typeof openai?.text === \"string\" && openai.text.trim()) {\n return openai.text.trim();\n }\n\n return null;\n}\n\nfunction extractDriveUrl(it) {\n return it.json?.webContentLink || it.json?.webViewLink || null;\n}\n\nfunction formatTmpfilesPublicUrl(it) {\n const raw = it.json?.data?.url;\n if (!raw) return null;\n\n return raw.replace(\n /^http:\\/\\/tmpfiles\\.org\\/(\\d+)\\/(.*)$/i,\n \"https://tmpfiles.org/dl/$1/$2\"\n );\n}\n\nconst rows = items.map((it, idx) => ({\n n: idx + 1,\n desc: extractOpenAIText(it) || \"No description\",\n url: extractDriveUrl(it) || \"No link\",\n url_public: formatTmpfilesPublicUrl(it) || \"No link\",\n}));\n\nreturn [{\n json: {\n image1Description: rows[0]?.desc || \"No description\",\n image2Description: rows[1]?.desc || \"No description\",\n image3Description: rows[2]?.desc || \"No description\",\n\n // URLs Drive\n image1Url: rows[0]?.url || \"No link\",\n image2Url: rows[1]?.url || \"No link\",\n image3Url: rows[2]?.url || \"No link\",\n imageUrls: rows.map(r => r.url).filter(u => u && u !== \"No link\"),\n\n // URLs publiques format\u00e9es (tmpfiles \u2192 /dl/)\n image1Url_public: rows[0]?.url_public || \"No link\",\n image2Url_public: rows[1]?.url_public || \"No link\",\n image3Url_public: rows[2]?.url_public || \"No link\",\n imageUrls_public: rows\n .map(r => r.url_public)\n .filter(u => u && u !== \"No link\"),\n\n allDescriptions: rows.map(r => `Image ${r.n}: ${r.desc}`).join(\"\\n\\n\"),\n }\n}];\n"
},
"typeVersion": 2
},
{
"id": "62e6048c-75d7-44a0-becd-5081de7c2cba",
"name": "OpenAI Chat Model",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
"position": [
912,
-64
],
"parameters": {
"model": {
"__rl": true,
"mode": "list",
"value": "gpt-4.1-mini"
},
"options": {},
"responsesApiEnabled": false
},
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.3
},
{
"id": "9f06b5df-3e84-40b0-bf14-c53004137a0f",
"name": "Structured Output Parser",
"type": "@n8n/n8n-nodes-langchain.outputParserStructured",
"position": [
1168,
-64
],
"parameters": {
"jsonSchemaExample": "{\n\t\"image_prompt\": \"string\"\n}"
},
"typeVersion": 1.3
},
{
"id": "20269caf-083b-4244-8144-0d620f2c2d4c",
"name": "NanoBanana: Create Image",
"type": "n8n-nodes-base.httpRequest",
"position": [
1328,
-336
],
"parameters": {
"url": "https://api.atlascloud.ai/api/v1/model/generateImage",
"method": "POST",
"options": {
"response": {
"response": {
"responseFormat": "json"
}
}
},
"jsonBody": "={\n \"model\": \"google/nano-banana-pro/edit\",\n \"aspect_ratio\": \"1:1\",\n \"enable_base64_output\": false,\n \"enable_sync_mode\": false,\n \"images\": {{ JSON.stringify($('Aggregate descriptions').item.json.imageUrls_public) }},\n \"output_format\": \"png\",\n\"prompt\": \"{{ \n ($json.output.image_prompt || '')\n .replace(/\\r?\\n/g, '\\\\n')\n .replace(/\"/g, '\\\\\"')\n}}\",\n \"resolution\": \"2k\"\n}",
"sendBody": true,
"sendHeaders": true,
"specifyBody": "json",
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "Bearer <__PLACEHOLDER_VALUE__atlascloud Key__>"
},
{
"name": "Content-Type",
"value": "application/json"
}
]
}
},
"typeVersion": 4.3
},
{
"id": "4172a90b-185d-4086-ab2f-f376c796e09d",
"name": "Build Public Image URL",
"type": "n8n-nodes-base.httpRequest",
"position": [
304,
-336
],
"parameters": {
"url": "https://tmpfiles.org/api/v1/upload",
"method": "POST",
"options": {
"response": {
"response": {
"responseFormat": "json"
}
}
},
"sendBody": true,
"contentType": "multipart-form-data",
"bodyParameters": {
"parameters": [
{
"name": "file",
"parameterType": "formBinaryData",
"inputDataFieldName": "image"
}
]
}
},
"typeVersion": 4.3
},
{
"id": "74d2fd99-39e5-4c8f-b543-eee7a5998625",
"name": "Wait",
"type": "n8n-nodes-base.wait",
"position": [
1552,
-336
],
"parameters": {
"unit": "minutes"
},
"typeVersion": 1.1
},
{
"id": "6fa18932-7a9c-4e12-a546-56a9d4c28e6b",
"name": "Download Edited Image",
"type": "n8n-nodes-base.httpRequest",
"position": [
1776,
-336
],
"parameters": {
"url": "=https://api.atlascloud.ai/api/v1/model/prediction/{{ $json.data.id }}",
"options": {
"response": {
"response": {
"responseFormat": "json"
}
}
},
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "Bearer <__PLACEHOLDER_VALUE__atlascloud Key__>"
},
{
"name": "Content-Type",
"value": "application/json"
}
]
}
},
"typeVersion": 4.3
},
{
"id": "4a816d1f-6a14-4151-9847-979eb5871cc2",
"name": "Append row in sheet",
"type": "n8n-nodes-base.googleSheets",
"position": [
2448,
-336
],
"parameters": {
"columns": {
"value": {
"status": "nanobanana_done",
"image_1": "={{ $('Aggregate descriptions').item.json.image1Url }}",
"image_2": "={{ $('Aggregate descriptions').item.json.image1Url }}",
"image_3": "={{ $('Aggregate descriptions').item.json.image3Url }}",
"description_all": "={{ $('Aggregate descriptions').item.json.allDescriptions }}",
"image_nanobanana": "={{ $json.webContentLink }}"
},
"schema": [
{
"id": "status",
"type": "string",
"display": true,
"required": false,
"displayName": "status",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "image_1",
"type": "string",
"display": true,
"required": false,
"displayName": "image_1",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "image_2",
"type": "string",
"display": true,
"required": false,
"displayName": "image_2",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "image_3",
"type": "string",
"display": true,
"required": false,
"displayName": "image_3",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "description_all",
"type": "string",
"display": true,
"required": false,
"displayName": "description_all",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "image_nanobanana",
"type": "string",
"display": true,
"required": false,
"displayName": "image_nanobanana",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "image_contactsheet",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "image_contactsheet",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "new_image_1",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "new_image_1",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "new_image_2",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "new_image_2",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "new_image_3",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "new_image_3",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "new_image_4",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "new_image_4",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "new_image_5",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "new_image_5",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "new_image_6",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "new_image_6",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "video_1",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "video_1",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "video_2",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "video_2",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "video_3",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "video_3",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "video_4",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "video_4",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "video_5",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "video_5",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "video_6",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "video_6",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "Final video",
"type": "string",
"display": true,
"removed": true,
"required": false,
"displayName": "Final video",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "defineBelow",
"matchingColumns": [],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"operation": "append",
"sheetName": {
"__rl": true,
"mode": "id",
"value": "=<__PLACEHOLDER_VALUE__Sheet Tab Name__>"
},
"documentId": {
"__rl": true,
"mode": "id",
"value": "=<__PLACEHOLDER_VALUE__Google Sheets Document ID__>"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.7
},
{
"id": "f36f01f2-14c1-4a9f-b81c-a04a7154cd54",
"name": "Download Final PNG (binary)",
"type": "n8n-nodes-base.httpRequest",
"position": [
2000,
-336
],
"parameters": {
"url": "={{ $json.data.outputs[0] }}",
"options": {
"response": {
"response": {
"responseFormat": "file"
}
}
}
},
"typeVersion": 4.3
},
{
"id": "1a8f03bd-254e-4367-9a07-dd25337765d2",
"name": "Upload file Nanobanana",
"type": "n8n-nodes-base.googleDrive",
"position": [
2224,
-336
],
"parameters": {
"name": "={{ $json.data.id }}",
"driveId": {
"__rl": true,
"mode": "id",
"value": "=<__PLACEHOLDER_VALUE__Google DRIVE Document ID___>"
},
"options": {},
"folderId": {
"__rl": true,
"mode": "id",
"value": "=<__PLACEHOLDER_VALUE__Google DRIVE Document ID___>"
}
},
"credentials": {
"googleDriveOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 3
},
{
"id": "1ca249a0-6ac1-4512-93f8-63baa120180e",
"name": "Note - Workflow Overview",
"type": "n8n-nodes-base.stickyNote",
"position": [
-704,
-768
],
"parameters": {
"color": 7,
"width": 1376,
"height": 888,
"content": "## Step 1: Input Validation\n**Form Trigger** receives 3 images from user\n\n**If** node checks all 3 images exist\n- \u2713 True: Continue to processing\n- \u2717 False: Return error message\n\nFor each image in parallel:\n- **Upload file** \u2192 Google Drive (permanent storage)\n- **Analyze image** \u2192 GPT-4O describes content\n- **Build Public URL** \u2192 tmpfiles.org (public access)"
},
"typeVersion": 1
},
{
"id": "654ea1aa-3071-4b11-823b-5c4040ec715d",
"name": "Generate Image Prompt",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
976,
-336
],
"parameters": {
"text": "=Your task is to create an image prompt following the system guidelines. \nEnsure that the reference image is represented as **accurately as possible**, including all text elements. \n\nUse the following inputs: \n\n- **IMAGES\u2019s description:** \n{{ $json.allDescriptions }}\n\n",
"options": {
"systemMessage": "=You output a prompt that is a variation of the prompt below. Follow this prompt exactly but just change:\n\n-the hand positioning based on what makes sense for the product\n-how the product is worn and where it is placed\n\neverything else stays the same\n\n***\n\nShow a high fashion studio photoshoot image of this reference character as a photorealistic model wearing the featured apparel and product, captured as a full body shot. The model looks slightly past the camera with a bored expression and raised eyebrows. One hand is lifted, with two fingers interacting with or touching the featured product in a natural, stylish way.\n\nThe setting is a clean studio environment with a solid color background that matches the primary color of the character. The featured product is intentionally prominent.\n\nThe image is shot from a low angle, looking up at the subject to emphasize presence and dominance.\n\nThe photo is captured on Fuji Velvia film using a 55mm prime lens with hard flash lighting. Light is concentrated on the subject and softly fades toward the edges of the frame. The image is intentionally overexposed, with visible film grain and heavy oversaturation. Skin appears shiny, almost oily, and the featured product shows harsh white reflections that highlight its surface and form.\n"
},
"promptType": "define",
"hasOutputParser": true
},
"typeVersion": 3.1
},
{
"id": "199181e7-6836-458b-9bbc-dabc814b3225",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1488,
-768
],
"parameters": {
"width": 720,
"height": 880,
"content": "## \ud83d\ude80 AI Image Generation Workflow\n\nThis workflow generates studio-quality e-commerce product images from **exactly 3 reference photos** using AI vision and **NanoBanana Pro**.\n\n## \ud83d\udd04 How it works\n\n1. A form collects **3 images**\n2. Inputs are validated (missing files \u2192 error)\n3. Images are processed in parallel:\n - Stored in Google Drive \n - Analyzed with AI vision (GPT-4O) \n - Converted to public URLs\n4. Descriptions are aggregated\n5. An AI agent generates a photoshoot prompt\n6. NanoBanana Pro creates the final image\n7. The result is stored and logged\n\n**Flow:** \nForm \u2192 Validation \u2192 Analysis \u2192 Prompt \u2192 Image \u2192 Storage\n\n## \u2699\ufe0f Setup steps\n\n1. Add credentials:\n - Google Drive & Sheets (OAuth) \n - OpenAI API key \n - AtlasCloud API key\n2. Replace all `<__PLACEHOLDER_VALUE__>` fields\n3. Ensure Drive folders are writable\n4. Keep input limited to **3 images**\n\n# \ud83d\udcd8 Documentation \n- Access detailed setup instructions, API config, platform connection guides, and workflow customization tips:\n\ud83d\udcce [Open the full documentation on Notion](https://automatisation.notion.site/Create-scalable-e-commerce-product-images-from-photos-using-NanoBanana-Pro-2e33d6550fd9808e8891f7d606b49df7?source=copy_link)"
},
"typeVersion": 1
},
{
"id": "4ba76a94-7ad8-4abf-a301-733bcfb2aafe",
"name": "Note - Workflow Overview1",
"type": "n8n-nodes-base.stickyNote",
"position": [
704,
-768
],
"parameters": {
"color": 7,
"width": 1936,
"height": 888,
"content": "## Step 2: Image Generation\n**Aggregate descriptions** combines all 3 image descriptions\n\n**AI Agent** (GPT-4.1-mini) creates a fashion photoshoot prompt:\n- Uses image descriptions as input\n- Outputs structured JSON with image_prompt field\n\n**NanoBanana: Create Image** sends request to API\n- Uses public image URLs and AI-generated prompt\n- API \u2192 www.atlascloud.ai"
},
"typeVersion": 1
}
],
"active": false,
"settings": {
"availableInMCP": false,
"executionOrder": "v1"
},
"versionId": "5397c807-b065-428b-a4b2-234fee032b7a",
"connections": {
"If": {
"main": [
[
{
"node": "Normalize binary names",
"type": "main",
"index": 0
}
],
[
{
"node": "Error Response - Missing Files",
"type": "main",
"index": 0
}
]
]
},
"Wait": {
"main": [
[
{
"node": "Download Edited Image",
"type": "main",
"index": 0
}
]
]
},
"Merge": {
"main": [
[
{
"node": "Aggregate descriptions",
"type": "main",
"index": 0
}
]
]
},
"Upload file": {
"main": [
[
{
"node": "Merge",
"type": "main",
"index": 0
}
]
]
},
"Split images": {
"main": [
[
{
"node": "Upload file",
"type": "main",
"index": 0
},
{
"node": "Analyze image",
"type": "main",
"index": 0
},
{
"node": "Build Public Image URL",
"type": "main",
"index": 0
}
]
]
},
"Analyze image": {
"main": [
[
{
"node": "Merge",
"type": "main",
"index": 2
}
]
]
},
"OpenAI Chat Model": {
"ai_languageModel": [
[
{
"node": "Generate Image Prompt",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Download Edited Image": {
"main": [
[
{
"node": "Download Final PNG (binary)",
"type": "main",
"index": 0
}
]
]
},
"Generate Image Prompt": {
"main": [
[
{
"node": "NanoBanana: Create Image",
"type": "main",
"index": 0
}
]
]
},
"Aggregate descriptions": {
"main": [
[
{
"node": "Generate Image Prompt",
"type": "main",
"index": 0
}
]
]
},
"Build Public Image URL": {
"main": [
[
{
"node": "Merge",
"type": "main",
"index": 1
}
]
]
},
"Normalize binary names": {
"main": [
[
{
"node": "Split images",
"type": "main",
"index": 0
}
]
]
},
"Upload file Nanobanana": {
"main": [
[
{
"node": "Append row in sheet",
"type": "main",
"index": 0
}
]
]
},
"Form Trigger (3 images)": {
"main": [
[
{
"node": "If",
"type": "main",
"index": 0
}
]
]
},
"NanoBanana: Create Image": {
"main": [
[
{
"node": "Wait",
"type": "main",
"index": 0
}
]
]
},
"Structured Output Parser": {
"ai_outputParser": [
[
{
"node": "Generate Image Prompt",
"type": "ai_outputParser",
"index": 0
}
]
]
},
"Download Final PNG (binary)": {
"main": [
[
{
"node": "Upload file Nanobanana",
"type": "main",
"index": 0
}
]
]
}
}
}
Credentials you'll need
Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.
googleDriveOAuth2ApigoogleSheetsOAuth2ApiopenAiApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
This workflow automates the creation of high-quality, AI-generated product images using NanoBanana Pro. It analyzes multiple reference images, generates a professional photoshoot-style prompt, creates a new image, and stores the final result with a public URL for reuse.
Source: https://n8n.io/workflows/12645/ — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
🎯 Create viral TikToks, Shorts, Reels, podcasts, and ASMR videos in minutes — all on autopilot.
Generate AI viral videos with NanoBanana & VEO3, shared on socials via Blotato 2. Uses @blotato/n8n-nodes-blotato, googleSheets, lmChatOpenAi, toolThink. Event-driven trigger; 94 nodes.
The best content automation template in the market is now even better—with “deep research” on time-sensitive topics\! Unlike most n8n content automation templates that are mainly for “demo purposes,”
This template is designed for marketers, content creators, and e-commerce brands who want to automate the creation of professional ad videos at scale. It’s ideal for teams looking to generate consiste
Digistars - Scrape & Crawl. Uses httpRequest, n8n-nodes-firecrawl-scraper, googleSheets, lmChatOpenAi. Event-driven trigger; 63 nodes.