This workflow follows the Editimage → HTTP Request 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 →
{
"nodes": [
{
"id": "a30e02b0-b807-4a4c-b2a6-19bacf5f2f8f",
"name": "When clicking \"Test workflow\"",
"type": "n8n-nodes-base.manualTrigger",
"position": [
800,
180
],
"parameters": {},
"typeVersion": 1
},
{
"id": "558afdb5-7311-48f1-9464-01b6933eaffe",
"name": "Get Meta BG",
"type": "n8n-nodes-base.editImage",
"position": [
1300,
60
],
"parameters": {
"operation": "information"
},
"typeVersion": 1
},
{
"id": "66bf1414-725b-40e3-be08-76f02a5d130f",
"name": "Nest Top Meta",
"type": "n8n-nodes-base.set",
"position": [
1480,
320
],
"parameters": {
"options": {
"includeBinary": true
},
"assignments": {
"assignments": [
{
"id": "2fb3fd91-c13d-45ce-a7ec-612319a008fc",
"name": "metaTop",
"type": "object",
"value": "={{ $json }}"
}
]
}
},
"typeVersion": 3.3
},
{
"id": "29e77ce2-15a0-47a8-8b1c-8f457ae435c6",
"name": "Nest Bg Meta",
"type": "n8n-nodes-base.set",
"position": [
1480,
60
],
"parameters": {
"options": {
"includeBinary": true
},
"assignments": {
"assignments": [
{
"id": "2fb3fd91-c13d-45ce-a7ec-612319a008fc",
"name": "metaBg",
"type": "object",
"value": "={{ $json }}"
}
]
}
},
"typeVersion": 3.3
},
{
"id": "dcdf4737-f881-4414-8fdb-1ce334e60093",
"name": "Calculate Center",
"type": "n8n-nodes-base.code",
"position": [
2280,
180
],
"parameters": {
"mode": "runOnceForEachItem",
"jsCode": "\n\n const centerX = ($input.item.json.metaBg.size.width + $input.item.json.metaTop.size.width) / 2;\n const centerY = ($input.item.json.metaBg.size.height + $input.item.json.metaTop.size.height) / 2;\n\n $input.item.json.center = { x: centerX, y: centerY };\n\nreturn $input.item"
},
"typeVersion": 2
},
{
"id": "7b146616-cbc7-4e21-a899-46fdc8e5c914",
"name": "Get Logo for the Watermark",
"type": "n8n-nodes-base.httpRequest",
"position": [
1100,
320
],
"parameters": {
"url": "https://cloud.let-the-work-flow.com/workflow-data/logo-shadow.png",
"options": {}
},
"typeVersion": 4.2
},
{
"id": "7167d1b8-f0c4-4068-b5c8-bb23d5a5a589",
"name": "Get the Image for Background",
"type": "n8n-nodes-base.httpRequest",
"position": [
1100,
60
],
"parameters": {
"url": "https://cloud.let-the-work-flow.com/workflow-data/robot-1.png",
"options": {}
},
"typeVersion": 4.2
},
{
"id": "df6b4e01-76aa-42dd-bf1f-8eb259cd4079",
"name": "Wait for both Images and merge Binary in one Item",
"type": "n8n-nodes-base.merge",
"position": [
1980,
180
],
"parameters": {
"mode": "combine",
"options": {},
"combinationMode": "mergeByPosition"
},
"typeVersion": 2.1
},
{
"id": "d5161149-275c-4e2d-9d55-7f1c18716933",
"name": "Rename Image Binary Top Image",
"type": "n8n-nodes-base.code",
"position": [
1660,
320
],
"parameters": {
"mode": "runOnceForEachItem",
"jsCode": "$input.item.binary.top = $input.item.binary.data;\ndelete $input.item.binary.data;\nreturn $input.item;"
},
"typeVersion": 2
},
{
"id": "90b0e990-d330-4875-b492-28d52019784d",
"name": "Rename Image Binary Background Image",
"type": "n8n-nodes-base.code",
"position": [
1660,
60
],
"parameters": {
"mode": "runOnceForEachItem",
"jsCode": "$input.item.binary.bg = $input.item.binary.data;\ndelete $input.item.binary.data;\nreturn $input.item;"
},
"typeVersion": 2
},
{
"id": "a2b3eaa3-61bb-4e91-a225-b6a9b5dd725c",
"name": "Get Meta Top",
"type": "n8n-nodes-base.editImage",
"position": [
1300,
320
],
"parameters": {
"operation": "information"
},
"typeVersion": 1
},
{
"id": "46b4e344-8ea6-4d87-9dc3-c3d80f17a9d5",
"name": "Let \"top\" overlay \"bg\"",
"type": "n8n-nodes-base.editImage",
"position": [
2600,
180
],
"parameters": {
"options": {
"format": "jpeg",
"fileName": "out.png"
},
"operation": "composite",
"positionX": "={{ $json.center.x - $json.metaTop.size.width }}",
"positionY": "={{ $json.center.y - $json.metaTop.size.height }}",
"dataPropertyName": "bg",
"dataPropertyNameComposite": "top"
},
"typeVersion": 1
},
{
"id": "ee7787f1-c717-416c-b076-18200e3109a0",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
1020,
-69.74382694102701
],
"parameters": {
"width": 820.7320856852112,
"height": 612.1135700636542,
"content": "## Retrieve the Background Image and fetch Meta from the File\n### Like Sizes, to properly place the \"Top Image\" a.k.a \"Watermark\" a.k.a \"Overlay\" above the \"Background\"-Image"
},
"typeVersion": 1
},
{
"id": "80925b86-42dc-4cf9-8a3b-b8df913d4d8c",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
2180,
60
],
"parameters": {
"width": 296.5141962579569,
"height": 568.2663488290325,
"content": "## Calculate the Position for the \"Top\" Image\n\n\n\n\n\n\n\n\n\n\n\n\n\nWe want to place the \"Top\"-Image it dead-center on the \"Background\"-Image. But the upper-left-corner is the origin for the operation. \n\nYou may adjust it to your needs, to \u2013 for example adjust the size of your Overlay-Image, or place it in some corner. Adjust the Formular to your needs.\n\n**\u26a0\ufe0f Limitation:** The Image that Overlays the Background-Image has to be <= the size of the background image to work properly."
},
"typeVersion": 1
},
{
"id": "89dafe6a-d49a-43f7-94d2-3c5de5b67c9f",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
2520,
360
],
"parameters": {
"color": 4,
"width": 257.68541919015513,
"height": 99.86957475347333,
"content": "### \ud83d\uddbc\ufe0f Binary Property *bg* should now be the composite image and be overlayed by *top*"
},
"typeVersion": 1
},
{
"id": "384bd626-fdbb-4073-ad9d-671b4aefe19e",
"name": "Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
301.53703835383794,
-60
],
"parameters": {
"width": 448.40729941128825,
"height": 745.9248098393447,
"content": "## Instructions\n\nThis automation *overlays* a `background` image with another image, making it easy to add watermarks or logos.\n\nYou can use this automation to **watermark** your images by overlaying them with a transparent version of your logo. If you'd like to **place your logo in a specific corner**, feel free to _adjust the position_ of the overlay image in the code node.\n\n### How it Works\n\n1. Both images are downloaded, so we can process binary files (you can modify the source, tho.)\n2. We extract metadata, focusing on the dimensions of each image.\n3. The position of the overlay image is calculated (default: dead center of the background image).\n4. The two images are *composited* together.\n\n### Limitations and Optimization Opportunities\n\n1. The overlay image must be the same size or smaller than the background image for proper alignment.\n2. The overlay image does not automatically scale to match the proportions of the background image.\n\n \nEnjoy the workflow! \u2764\ufe0f \n[let the workf low](https://let-the-work-flow.com) \u2014 Workflow Automation & Development"
},
"typeVersion": 1
}
],
"connections": {
"Get Meta BG": {
"main": [
[
{
"node": "Nest Bg Meta",
"type": "main",
"index": 0
}
]
]
},
"Get Meta Top": {
"main": [
[
{
"node": "Nest Top Meta",
"type": "main",
"index": 0
}
]
]
},
"Nest Bg Meta": {
"main": [
[
{
"node": "Rename Image Binary Background Image",
"type": "main",
"index": 0
}
]
]
},
"Nest Top Meta": {
"main": [
[
{
"node": "Rename Image Binary Top Image",
"type": "main",
"index": 0
}
]
]
},
"Calculate Center": {
"main": [
[
{
"node": "Let \"top\" overlay \"bg\"",
"type": "main",
"index": 0
}
]
]
},
"Get Logo for the Watermark": {
"main": [
[
{
"node": "Get Meta Top",
"type": "main",
"index": 0
}
]
]
},
"Get the Image for Background": {
"main": [
[
{
"node": "Get Meta BG",
"type": "main",
"index": 0
}
]
]
},
"Rename Image Binary Top Image": {
"main": [
[
{
"node": "Wait for both Images and merge Binary in one Item",
"type": "main",
"index": 1
}
]
]
},
"When clicking \"Test workflow\"": {
"main": [
[
{
"node": "Get the Image for Background",
"type": "main",
"index": 0
},
{
"node": "Get Logo for the Watermark",
"type": "main",
"index": 0
}
]
]
},
"Rename Image Binary Background Image": {
"main": [
[
{
"node": "Wait for both Images and merge Binary in one Item",
"type": "main",
"index": 0
}
]
]
},
"Wait for both Images and merge Binary in one Item": {
"main": [
[
{
"node": "Calculate Center",
"type": "main",
"index": 0
}
]
]
}
}
}
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
How this works
This workflow streamlines the creation of customised promotional images by overlaying logos and metadata onto background visuals, saving hours of manual design work for marketers and content creators. It suits small teams or individuals who need quick, consistent branding without advanced graphic skills, using the editImage node to precisely position elements like watermarks and sticky notes. The key step involves fetching your logo and background image via httpRequest, then merging them with calculated positioning to produce a polished final output ready for social media or emails.
Use this workflow when generating event flyers or product banners on demand, especially for recurring campaigns with variable details like dates or titles. Avoid it for complex designs requiring multiple layers or animations, as it focuses on straightforward overlays; opt for dedicated tools like Canva in those cases. Common variations include swapping httpRequest sources for different image libraries or adding conditional nodes to adjust layouts based on image dimensions.
About this workflow
Code Editimage. Uses manualTrigger, editImage, httpRequest, stickyNote. Event-driven trigger; 16 nodes.
Source: https://github.com/Zie619/n8n-workflows — 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.
Manual Editimage. Uses manualTrigger, httpRequest, itemLists, editImage. Event-driven trigger; 12 nodes.
Manual Editimage. Uses manualTrigger, httpRequest, itemLists, editImage. Event-driven trigger; 12 nodes.
Code Editimage. Uses manualTrigger, lmChatGoogleGemini, sort, stickyNote. Event-driven trigger; 20 nodes.
Code Editimage. Uses manualTrigger, lmChatGoogleGemini, sort, stickyNote. Event-driven trigger; 20 nodes.
Add text to an image downloaded from the internet. Uses manualTrigger, editImage, httpRequest. Event-driven trigger; 3 nodes.