You can edit the below JavaScript code to customize the image tool.
Apply Changes
function processImage(originalImg, bottomText = "X", topText = "I KILLED", dramaticFilter = 0, drawRedCross = 0) {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
// Ensure valid dimensions
if (!originalImg || !originalImg.width || !originalImg.height) {
return canvas;
}
canvas.width = originalImg.width;
canvas.height = originalImg.height;
// Draw original image
ctx.drawImage(originalImg, 0, 0);
// Apply Dramatic Filter if requested (Grayscale with red tint + Vignette)
if (Number(dramaticFilter) > 0) {
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
const data = imageData.data;
for (let i = 0; i < data.length; i += 4) {
const r = data[i];
const g = data[i + 1];
const b = data[i + 2];
const luma = r * 0.299 + g * 0.587 + b * 0.114;
// Push towards a dramatic dark tone with a slight red undertone
data[i] = Math.min(255, luma + 30);
data[i + 1] = Math.max(0, luma - 20);
data[i + 2] = Math.max(0, luma - 20);
}
ctx.putImageData(imageData, 0, 0);
// Add Vignette effect
const gradient = ctx.createRadialGradient(
canvas.width / 2, canvas.height / 2, Math.min(canvas.width, canvas.height) * 0.2,
canvas.width / 2, canvas.height / 2, Math.max(canvas.width, canvas.height) * 0.75
);
gradient.addColorStop(0, 'rgba(0, 0, 0, 0)');
gradient.addColorStop(1, 'rgba(0, 0, 0, 0.85)');
ctx.fillStyle = gradient;
ctx.fillRect(0, 0, canvas.width, canvas.height);
}
// Draw a giant red "X" across the image (like a crossed-out target)
if (Number(drawRedCross) > 0) {
ctx.strokeStyle = 'rgba(220, 0, 0, 0.75)';
ctx.lineWidth = Math.min(canvas.width, canvas.height) * 0.05;
ctx.lineCap = 'round';
ctx.beginPath();
ctx.moveTo(canvas.width * 0.15, canvas.height * 0.15);
ctx.lineTo(canvas.width * 0.85, canvas.height * 0.85);
ctx.moveTo(canvas.width * 0.85, canvas.height * 0.15);
ctx.lineTo(canvas.width * 0.15, canvas.height * 0.85);
ctx.stroke();
}
// Helper function to draw Impact-style meme text with auto-wrapping
function drawMemeText(text, isBottom) {
if (!text || text.trim() === '') return;
const txt = String(text).toUpperCase();
let fontSize = Math.floor(canvas.height * 0.12);
if (fontSize < 24) fontSize = 24;
let maxFont = canvas.width * 0.15;
if (fontSize > maxFont) fontSize = maxFont;
ctx.font = `bold ${fontSize}px Impact, "Arial Black", sans-serif`;
ctx.fillStyle = 'white';
ctx.strokeStyle = 'black';
ctx.textAlign = 'center';
ctx.lineJoin = 'round';
const padding = Math.max(10, canvas.height * 0.03);
const maxWidth = canvas.width - padding * 2;
let words = txt.split(' ');
let lines = [];
let currentLine = words[0] || '';
for (let i = 1; i < words.length; i++) {
let word = words[i];
let width = ctx.measureText(currentLine + ' ' + word).width;
if (width < maxWidth) {
currentLine += ' ' + word;
} else {
lines.push(currentLine);
currentLine = word;
}
}
if (currentLine) {
lines.push(currentLine);
}
const lineHeight = fontSize * 1.15;
lines.forEach((line, index) => {
let y;
if (isBottom) {
y = canvas.height - padding - (lines.length - 1 - index) * lineHeight;
ctx.textBaseline = 'bottom';
} else {
y = padding + index * lineHeight;
ctx.textBaseline = 'top';
}
// Re-scale font if a single continuous word exceeds maximum width
let currentFontSize = fontSize;
ctx.font = `bold ${currentFontSize}px Impact, "Arial Black", sans-serif`;
while (ctx.measureText(line).width > maxWidth && currentFontSize > 10) {
currentFontSize -= 2;
ctx.font = `bold ${currentFontSize}px Impact, "Arial Black", sans-serif`;
}
ctx.lineWidth = Math.max(3, currentFontSize * 0.06);
ctx.strokeText(line, canvas.width / 2, y);
ctx.fillText(line, canvas.width / 2, y);
// Reset font parameters for the next line
ctx.font = `bold ${fontSize}px Impact, "Arial Black", sans-serif`;
});
}
// Render meme overlay text
drawMemeText(topText, false);
drawMemeText(bottomText, true);
return canvas;
}
Apply Changes