You can edit the below JavaScript code to customize the image tool.
Apply Changes
async function processImage(originalImg, text = "MS PAINT", charSize = 64, spacing = 8, backgroundColor = "#FFFFFF") {
// This tool translates a string of text into a sequence of images drawn in an
// MS Paint style, where each letter corresponds to a simple object (e.g., A for Apple).
// The originalImg parameter is ignored as this is a text-to-image generator.
const drawingFns = {
// Helper function to set a consistent MS Paint style
_setStyle: (ctx, w) => {
ctx.strokeStyle = '#000000';
ctx.lineWidth = Math.max(2, Math.round(w * 0.04));
ctx.lineJoin = 'round';
ctx.lineCap = 'round';
},
// A for Apple
'A': (ctx, w, h) => {
drawingFns._setStyle(ctx, w);
// Apple Body
ctx.fillStyle = '#FF4136'; // Red
ctx.beginPath();
ctx.arc(w * 0.5, h * 0.6, w * 0.35, 0, Math.PI * 2);
ctx.fill();
ctx.stroke();
// Dip
ctx.fillStyle = backgroundColor;
ctx.beginPath();
ctx.arc(w*0.5, h*0.3, w*0.1, 0, Math.PI*2);
ctx.fill();
// Stem
ctx.beginPath();
ctx.moveTo(w * 0.5, h * 0.35);
ctx.lineTo(w * 0.6, h * 0.15);
ctx.stroke();
// Leaf
ctx.fillStyle = '#2ECC40'; // Green
ctx.beginPath();
ctx.ellipse(w * 0.4, h * 0.3, w * 0.15, w * 0.08, -0.5, 0, Math.PI * 2);
ctx.fill();
ctx.stroke();
},
// B for Ball
'B': (ctx, w, h) => {
drawingFns._setStyle(ctx, w);
ctx.fillStyle = '#0074D9'; // Blue
ctx.beginPath();
ctx.arc(w / 2, h / 2, w * 0.4, 0, Math.PI * 2);
ctx.fill();
ctx.stroke();
ctx.fillStyle = '#FF4136'; // Red
ctx.beginPath();
ctx.arc(w / 2, h / 2, w * 0.4, -0.5, 1);
ctx.lineTo(w / 2, h / 2);
ctx.closePath();
ctx.fill();
},
// C for Cat
'C': (ctx, w, h) => {
drawingFns._setStyle(ctx, w);
ctx.fillStyle = '#FF851B'; // Orange
// Head
ctx.beginPath();
ctx.arc(w / 2, h / 2, w * 0.4, 0, Math.PI * 2);
ctx.fill();
ctx.stroke();
// Ears
ctx.beginPath();
ctx.moveTo(w * 0.2, h * 0.5);
ctx.lineTo(w * 0.3, h * 0.2);
ctx.lineTo(w * 0.4, h * 0.4);
ctx.moveTo(w * 0.8, h * 0.5);
ctx.lineTo(w * 0.7, h * 0.2);
ctx.lineTo(w * 0.6, h * 0.4);
ctx.fill();
ctx.stroke();
// Eyes
ctx.fillStyle = '#000000';
ctx.beginPath();
ctx.arc(w * 0.4, h * 0.5, w * 0.05, 0, Math.PI * 2);
ctx.arc(w * 0.6, h * 0.5, w * 0.05, 0, Math.PI * 2);
ctx.fill();
},
// D for Duck
'D': (ctx, w, h) => {
drawingFns._setStyle(ctx, w);
ctx.fillStyle = '#FFDC00'; // Yellow
// Body
ctx.beginPath();
ctx.ellipse(w * 0.45, h * 0.65, w * 0.3, h * 0.2);
ctx.fill();
ctx.stroke();
// Head
ctx.beginPath();
ctx.arc(w * 0.7, h * 0.4, w * 0.2, 0, Math.PI * 2);
ctx.fill();
ctx.stroke();
// Beak
ctx.fillStyle = '#FF851B'; // Orange
ctx.beginPath();
ctx.moveTo(w * 0.85, h * 0.4);
ctx.lineTo(w * 0.95, h * 0.45);
ctx.lineTo(w * 0.85, h * 0.5);
ctx.closePath();
ctx.fill();
ctx.stroke();
// Eye
ctx.fillStyle = '#000000';
ctx.beginPath();
ctx.arc(w * 0.75, h * 0.38, w * 0.04, 0, Math.PI * 2);
ctx.fill();
},
// E for Egg
'E': (ctx, w, h) => {
drawingFns._setStyle(ctx, w);
ctx.fillStyle = '#F0F0F0';
ctx.beginPath();
ctx.ellipse(w / 2, h / 2, w * 0.3, h * 0.4);
ctx.fill();
ctx.stroke();
},
// F for Fish
'F': (ctx, w, h) => {
drawingFns._setStyle(ctx, w);
ctx.fillStyle = '#FF851B'; // Orange
// Body
ctx.beginPath();
ctx.ellipse(w * 0.5, h * 0.5, w * 0.35, h * 0.25);
ctx.fill();
ctx.stroke();
// Tail
ctx.beginPath();
ctx.moveTo(w * 0.15, h * 0.5);
ctx.lineTo(w * 0.05, h * 0.3);
ctx.lineTo(w * 0.05, h * 0.7);
ctx.closePath();
ctx.fill();
ctx.stroke();
// Eye
ctx.fillStyle = '#FFFFFF';
ctx.beginPath();
ctx.arc(w * 0.7, h * 0.45, w * 0.1, 0, Math.PI * 2);
ctx.fill();
ctx.stroke();
ctx.fillStyle = '#000000';
ctx.beginPath();
ctx.arc(w * 0.72, h * 0.45, w * 0.05, 0, Math.PI * 2);
ctx.fill();
},
// G for Grapes
'G': (ctx, w, h) => {
drawingFns._setStyle(ctx, w);
ctx.fillStyle = '#B10DC9'; // Purple
const r = w * 0.12;
const positions = [
[0.5, 0.3], [0.35, 0.45], [0.65, 0.45],
[0.2, 0.65], [0.5, 0.65], [0.8, 0.65],
[0.35, 0.85], [0.65, 0.85]
];
positions.forEach(p => {
ctx.beginPath();
ctx.arc(w * p[0], h * p[1], r, 0, 2 * Math.PI);
ctx.fill();
ctx.stroke();
});
},
// H for House
'H': (ctx, w, h) => {
drawingFns._setStyle(ctx, w);
// Roof
ctx.fillStyle = '#A52A2A'; // Brown
ctx.beginPath();
ctx.moveTo(w * 0.1, h * 0.4);
ctx.lineTo(w * 0.5, h * 0.1);
ctx.lineTo(w * 0.9, h * 0.4);
ctx.closePath();
ctx.fill();
ctx.stroke();
// Base
ctx.fillStyle = '#F0E68C'; // Khaki
ctx.fillRect(w * 0.2, h * 0.4, w * 0.6, h * 0.5);
ctx.strokeRect(w * 0.2, h * 0.4, w * 0.6, h * 0.5);
},
// I for Ice Cream
'I': (ctx, w, h) => {
drawingFns._setStyle(ctx, w);
// Cone
ctx.fillStyle = '#F3D18B';
ctx.beginPath();
ctx.moveTo(w * 0.35, h * 0.4);
ctx.lineTo(w * 0.5, h * 0.9);
ctx.lineTo(w * 0.65, h * 0.4);
ctx.closePath();
ctx.fill();
ctx.stroke();
// Scoop
ctx.fillStyle = '#FFC0CB'; // Pink
ctx.beginPath();
ctx.arc(w * 0.5, h * 0.3, w * 0.2, 0, Math.PI * 2);
ctx.fill();
ctx.stroke();
},
// J for Jar
'J': (ctx, w, h) => {
drawingFns._setStyle(ctx, w);
ctx.fillStyle = 'rgba(173, 216, 230, 0.5)'; // Light blue, semi-transparent
// Lid
ctx.fillStyle = '#808080'; // Gray
ctx.fillRect(w*0.25, h*0.1, w*0.5, h*0.1);
ctx.strokeRect(w*0.25, h*0.1, w*0.5, h*0.1);
// Body
ctx.fillStyle = 'rgba(173, 216, 230, 0.5)';
ctx.beginPath();
ctx.rect(w * 0.2, h * 0.2, w * 0.6, h * 0.7);
ctx.fill();
ctx.stroke();
},
// K for Kite
'K': (ctx, w, h) => {
drawingFns._setStyle(ctx, w);
ctx.fillStyle = '#39CCCC'; // Teal
ctx.beginPath();
ctx.moveTo(w * 0.5, h * 0.1);
ctx.lineTo(w * 0.9, h * 0.5);
ctx.lineTo(w * 0.5, h * 0.9);
ctx.lineTo(w * 0.1, h * 0.5);
ctx.closePath();
ctx.fill();
ctx.stroke();
},
// L for Lemon
'L': (ctx, w, h) => {
drawingFns._setStyle(ctx, w);
ctx.fillStyle = '#FFDC00'; // Yellow
ctx.beginPath();
ctx.ellipse(w / 2, h / 2, w * 0.4, h * 0.3);
ctx.fill();
ctx.stroke();
ctx.beginPath();
ctx.arc(w*0.88, h*0.5, w*0.05, 0, Math.PI*2);
ctx.fill();
},
// M for Moon
'M': (ctx, w, h) => {
drawingFns._setStyle(ctx, w);
ctx.fillStyle = '#FDFD96'; // Pale Yellow
ctx.beginPath();
ctx.arc(w / 2, h / 2, w * 0.4, Math.PI * 1.5, Math.PI * 0.5);
ctx.arc(w * 0.4, h / 2, w * 0.3, Math.PI * 0.5, Math.PI * 1.5, true);
ctx.closePath();
ctx.fill();
ctx.stroke();
},
// N for Nest
'N': (ctx, w, h) => {
drawingFns._setStyle(ctx, w);
ctx.fillStyle = '#8B4513'; // Brown
ctx.beginPath();
ctx.ellipse(w/2, h*0.7, w*0.4, h*0.2);
ctx.fill(); ctx.stroke();
ctx.fillStyle = '#ADD8E6'; // Light Blue
ctx.beginPath();
ctx.arc(w*0.4, h*0.65, w*0.1, 0, 2*Math.PI);
ctx.fill(); ctx.stroke();
ctx.beginPath();
ctx.arc(w*0.6, h*0.65, w*0.1, 0, 2*Math.PI);
ctx.fill(); ctx.stroke();
},
// O for Orange
'O': (ctx, w, h) => {
drawingFns._setStyle(ctx, w);
ctx.fillStyle = '#FF851B'; // Orange
ctx.beginPath();
ctx.arc(w / 2, h / 2, w * 0.4, 0, Math.PI * 2);
ctx.fill();
ctx.stroke();
},
// P for Pencil
'P': (ctx, w, h) => {
drawingFns._setStyle(ctx, w);
ctx.save();
ctx.translate(w/2, h/2);
ctx.rotate(Math.PI / 4);
// Body
ctx.fillStyle = '#FFDC00'; // Yellow
ctx.fillRect(-w * 0.4, -h * 0.1, w * 0.6, h * 0.2);
ctx.strokeRect(-w * 0.4, -h * 0.1, w * 0.6, h * 0.2);
// Tip
ctx.fillStyle = '#F3D18B'; // Wood
ctx.beginPath();
ctx.moveTo(w * 0.2, -h * 0.1);
ctx.lineTo(w * 0.4, 0);
ctx.lineTo(w * 0.2, h * 0.1);
ctx.closePath();
ctx.fill(); ctx.stroke();
// Lead
ctx.fillStyle = '#111111';
ctx.beginPath();
ctx.moveTo(w*0.4, 0);
ctx.lineTo(w*0.45, -h*0.02);
ctx.lineTo(w*0.45, h*0.02);
ctx.closePath();
ctx.fill();
// Eraser
ctx.fillStyle = '#FFC0CB'; // Pink
ctx.fillRect(-w * 0.5, -h * 0.1, w * 0.1, h * 0.2);
ctx.strokeRect(-w * 0.5, -h * 0.1, w * 0.1, h * 0.2);
ctx.restore();
},
// Q for Queen's Crown
'Q': (ctx, w, h) => {
drawingFns._setStyle(ctx, w);
ctx.fillStyle = '#FFDC00'; // Yellow
ctx.beginPath();
ctx.moveTo(w*0.1, h*0.4);
ctx.lineTo(w*0.1, h*0.8);
ctx.lineTo(w*0.9, h*0.8);
ctx.lineTo(w*0.9, h*0.4);
ctx.lineTo(w*0.7, h*0.6);
ctx.lineTo(w*0.5, h*0.3);
ctx.lineTo(w*0.3, h*0.6);
ctx.closePath();
ctx.fill(); ctx.stroke();
},
// R for Rainbow
'R': (ctx, w, h) => {
const colors = ['#FF4136', '#FF851B', '#FFDC00', '#2ECC40', '#0074D9', '#B10DC9'];
const arcHeight = h * 0.1;
ctx.lineCap = 'butt';
for (let i = 0; i < colors.length; i++) {
ctx.lineWidth = arcHeight;
ctx.strokeStyle = colors[i];
ctx.beginPath();
ctx.arc(w / 2, h * 0.5, w*0.4 - i * arcHeight, Math.PI, 0);
ctx.stroke();
}
},
// S for Sun
'S': (ctx, w, h) => {
drawingFns._setStyle(ctx, w);
ctx.fillStyle = '#FFDC00'; // Yellow
ctx.beginPath();
ctx.arc(w / 2, h / 2, w * 0.25, 0, Math.PI * 2);
ctx.fill();
ctx.stroke();
for (let i = 0; i < 8; i++) {
const angle = (i / 8) * Math.PI * 2;
ctx.beginPath();
ctx.moveTo(w / 2 + Math.cos(angle) * w * 0.3, h / 2 + Math.sin(angle) * h * 0.3);
ctx.lineTo(w / 2 + Math.cos(angle) * w * 0.45, h / 2 + Math.sin(angle) * h * 0.45);
ctx.stroke();
}
},
// T for Tree
'T': (ctx, w, h) => {
drawingFns._setStyle(ctx, w);
// Trunk
ctx.fillStyle = '#A0522D';
ctx.fillRect(w * 0.4, h * 0.6, w * 0.2, h * 0.3);
ctx.strokeRect(w * 0.4, h * 0.6, w * 0.2, h * 0.3);
// Leaves
ctx.fillStyle = '#2ECC40';
ctx.beginPath();
ctx.arc(w / 2, h * 0.4, w * 0.3, 0, Math.PI * 2);
ctx.fill();
ctx.stroke();
},
// U for Umbrella
'U': (ctx, w, h) => {
drawingFns._setStyle(ctx, w);
// Handle
ctx.beginPath();
ctx.moveTo(w*0.5, h*0.4);
ctx.lineTo(w*0.5, h*0.8);
ctx.arc(w*0.4, h*0.8, w*0.1, 0, Math.PI);
ctx.stroke();
// Canopy
ctx.fillStyle = '#0074D9'; // Blue
ctx.beginPath();
ctx.arc(w/2, h*0.4, w*0.4, Math.PI, 0);
ctx.closePath();
ctx.fill();
ctx.stroke();
},
// V for Volcano
'V': (ctx, w, h) => {
drawingFns._setStyle(ctx, w);
ctx.fillStyle = '#A0522D';
ctx.beginPath();
ctx.moveTo(w*0.1, h*0.9);
ctx.lineTo(w*0.4, h*0.2);
ctx.lineTo(w*0.6, h*0.2);
ctx.lineTo(w*0.9, h*0.9);
ctx.closePath();
ctx.fill(); ctx.stroke();
// Lava
ctx.fillStyle = '#FF4136'; // Red
ctx.beginPath();
ctx.ellipse(w*0.5, h*0.25, w*0.1, h*0.05);
ctx.fill(); ctx.stroke();
},
// W for Watermelon
'W': (ctx, w, h) => {
drawingFns._setStyle(ctx, w);
// Green Rind
ctx.fillStyle = '#2ECC40';
ctx.beginPath();
ctx.arc(w/2, h*0.6, w*0.4, Math.PI, 0);
ctx.fill(); ctx.stroke();
// Red Fruit
ctx.fillStyle = '#FF4136'; // Red
ctx.beginPath();
ctx.arc(w/2, h*0.6, w*0.35, Math.PI, 0);
ctx.fill(); ctx.stroke();
},
// X for Xylophone
'X': (ctx, w, h) => {
drawingFns._setStyle(ctx, w);
ctx.save();
ctx.translate(w/2, h/2);
ctx.rotate(-0.3);
const colors = ['#FF4136', '#FFDC00', '#2ECC40'];
colors.forEach((c, i) => {
ctx.fillStyle = c;
const barWidth = w * (0.6 - i*0.1);
ctx.fillRect(-barWidth/2, h*(-0.2 + i*0.2), barWidth, h*0.15);
ctx.strokeRect(-barWidth/2, h*(-0.2 + i*0.2), barWidth, h*0.15);
});
ctx.restore();
},
// Y for Yo-yo
'Y': (ctx, w, h) => {
drawingFns._setStyle(ctx, w);
ctx.beginPath();
ctx.moveTo(w * 0.5, h * 0.1);
ctx.lineTo(w * 0.5, h * 0.4);
ctx.stroke();
ctx.fillStyle = '#B10DC9'; // Purple
ctx.beginPath();
ctx.arc(w * 0.5, h * 0.6, w * 0.25, 0, Math.PI * 2);
ctx.fill();
ctx.stroke();
},
// Z for Zig-zag
'Z': (ctx, w, h) => {
drawingFns._setStyle(ctx, w);
ctx.beginPath();
ctx.moveTo(w*0.2, h*0.2);
ctx.lineTo(w*0.8, h*0.2);
ctx.lineTo(w*0.2, h*0.8);
ctx.lineTo(w*0.8, h*0.8);
ctx.stroke();
},
// Numbers 0-9
...Object.fromEntries(Array.from({length: 10}, (_, i) => [
String(i),
(ctx, w, h) => {
drawingFns._setStyle(ctx, w);
ctx.lineWidth = Math.max(4, w * 0.1);
ctx.font = `bold ${h*0.8}px 'Comic Sans MS', 'Chalkboard SE', 'Marker Felt', 'Arial', sans-serif`;
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.fillStyle = '#001f3f'; // Navy
ctx.fillText(String(i), w / 2, h / 2);
ctx.strokeText(String(i), w / 2, h / 2);
}
])),
// Space character
' ': (ctx, w, h) => {
// Do nothing, leaves a blank space
},
// Default for unknown characters
'DEFAULT': (ctx, w, h) => {
drawingFns._setStyle(ctx, w);
ctx.font = `bold ${h*0.7}px 'Comic Sans MS', 'Chalkboard SE', 'Marker Felt', 'Arial', sans-serif`;
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.fillStyle = '#FF4136'; // Red
ctx.fillText('?', w / 2, h / 2);
ctx.strokeText('?', w / 2, h / 2);
}
};
const upperText = String(text).toUpperCase();
const chars = upperText.split('');
const numChars = chars.length;
if (numChars === 0) {
const emptyCanvas = document.createElement('canvas');
emptyCanvas.width = 1;
emptyCanvas.height = 1;
return emptyCanvas;
}
const canvasWidth = (numChars * charSize) + (Math.max(0, numChars - 1) * spacing);
const canvasHeight = charSize;
const canvas = document.createElement('canvas');
canvas.width = canvasWidth;
canvas.height = canvasHeight;
const ctx = canvas.getContext('2d');
// Draw background
ctx.fillStyle = backgroundColor;
ctx.fillRect(0, 0, canvas.width, canvas.height);
let currentX = 0;
for (const char of chars) {
const drawFn = drawingFns[char] || drawingFns.DEFAULT;
ctx.save();
ctx.translate(currentX, 0);
drawFn(ctx, charSize, charSize);
ctx.restore();
currentX += charSize + spacing;
}
return canvas;
}
Apply Changes