I have integrated Draw Things into my workflow, with the overall process illustrated in the diagram. I demonstrate how n8n works together with Draw Things to generate images, convert them to WebP format, and add overlay text. This setup enables automated image processing and efficient content generation.

Steps to reproduce:
- Assuming n8n is in Docker and DrawThings are on the host URL, it should be http://host.docker.internal:7860/sdapi/v1/txt2img. We need to use JSON, not fields, because n8n converts them to strings, and n8n has problems with interpretation. In my case, it’s:
{
"height": 576,
"width": 1024,
"seed": -1,
"prompt": "{{ $json.output.replaceAll('"', '\'').replaceAll('\n', '') }}",
"batch_size": 1
}- Next, we need to move the Base64 string to the file using the field
images[0]and put it in the data field. - We save PNG as e.g.
/tmp/{{ $now.format('yyyy-MM-dd_HH-mm-ss') }}.png - For conversion to WebP, we use a simple script and the SharpJS library executed as:
npm run convert -- {{ $json.fileName }}
// convert.js
const fs = require('fs');
const sharp = require('sharp');
async function convertPngToJpeg(filePath) {
const outputPath = filePath.replace(/\.png$/i, '.webp');
const input = fs.readFileSync(filePath);
const output = await sharp(input).webp().toBuffer();
fs.writeFileSync(outputPath, output);
console.log(`Converted: ${outputPath} end.`);
}
const inputPath = process.argv[2];
if (!inputPath) {
console.error('Usage: node convert.js <path-to-png>');
process.exit(1);
}
convertPngToJpeg(inputPath);- The next thing is to get the filename from stdout.:
{{ $json.stdout.match(/Converted: (.*) end./)[1] }}and pass it as filename - The last link is to read WebP, for example, sending it to WordPress (using the filename from the previous step).
Hope it helps or inspires someone to use different tools 🙂
EDIT: I have added watermark – still probably I will need to play a bit with alpha, and sizes:
// convert.js
const fs = require('fs');
const sharp = require('sharp');
async function convertPngToJpeg(filePath) {
const outputPath = filePath.replace(/\.png$/i, '.webp');
const { width, height } = await sharp(filePath).metadata();
const watermark = `
<svg width="${width}" height="${height}">
<style>
.watermark {
fill: rgba(255,255,255,0.4); /* main text color */
font-size: 18px;
font-family: sans-serif;
stroke: rgba(100,100,100,0.4); /* outline color */
stroke-width: 1px; /* thickness of outline */
paint-order: stroke fill; /* ensure stroke is drawn under fill */
}
</style>
<text x="${width - 20}" y="${height - 20}" text-anchor="end" class="watermark">
AI generated
</text>
</svg>
`;
await sharp(filePath)
.composite([{ input: Buffer.from(watermark) }])
.toFile(filePath + '_wm');
const input = fs.readFileSync(filePath + '_wm');
const output = await sharp(input).webp().toBuffer();
fs.writeFileSync(outputPath, output);
console.log(`Converted: ${outputPath} end.`);
}
const inputPath = process.argv[2];
if (!inputPath) {
console.error('Usage: node convert.js <path-to-png>');
process.exit(1);
}
convertPngToJpeg(inputPath); 