You can edit the below JavaScript code to customize the image tool.
Apply Changes
async function processImage(
originalImg,
title = "THE CYBERNATURAL CONJURING",
releaseDate = "SYS.DATE: 2027",
tagline = "YOUR DEMON CODES ARE EXECUTING..."
) {
// 1. Inject necessary fonts dynamically
const link = document.createElement('link');
link.rel = 'stylesheet';
link.href = 'https://fonts.googleapis.com/css2?family=Rubik+Glitch&family=Share+Tech+Mono&display=swap';
document.head.appendChild(link);
// Wait slightly to ensure fonts begin loading, then force the load
await new Promise(resolve => setTimeout(resolve, 100));
try {
await Promise.all([
document.fonts.load('30px "Rubik Glitch"'),
document.fonts.load('30px "Share Tech Mono"')
]);
} catch (e) {
console.warn('Custom fonts could not be loaded. Falling back to default fonts.', e);
}
// 2. Setup Canvas (Cinematic Poster Ratio 2:3)
const width = 800;
const height = 1200;
const canvas = document.createElement('canvas');
canvas.width = width;
canvas.height = height;
const ctx = canvas.getContext('2d');
// 3. Draw original image onto canvas (Cropped to fit)
const scale = Math.max(width / originalImg.width, height / originalImg.height);
const scaledW = originalImg.width * scale;
const scaledH = originalImg.height * scale;
const dx = (width - scaledW) / 2;
const dy = (height - scaledH) / 2;
ctx.drawImage(originalImg, dx, dy, scaledW, scaledH);
// 4. Color Grading and Chromatic Aberration Matrix (Cyber/Horror fusion)
const imgData = ctx.getImageData(0, 0, width, height);
const data = imgData.data;
const newData = new Uint8ClampedArray(data.length);
for (let y = 0; y < height; y++) {
// Create an organic wave for vertical distortion
const wave = Math.sin(y * 0.02) * 4;
const abShift = 6 + Math.floor(wave);
for (let x = 0; x < width; x++) {
const index = (y * width + x) * 4;
// Shift coordinates for chromatic aberration
const iRed = (y * width + Math.min(width - 1, Math.max(0, x + abShift))) * 4;
const iBlue = (y * width + Math.min(width - 1, Math.max(0, x - abShift))) * 4;
const r = data[iRed];
const g = data[index + 1];
const b = data[iBlue + 2];
// Calculate luminance for desaturated cyber-look
let lum = 0.299 * r + 0.587 * g + 0.114 * b;
// Boost cinematic contrast
lum = ((lum / 255 - 0.5) * 1.6 + 0.5) * 255;
// Apply matrixy cyber-teal and harsh horror reds
let finR = lum * 0.9;
let finG = lum * 1.1;
let finB = lum * 1.2;
// Pushing highlights into harsh demonic tones
if (lum > 170) {
finR = lum * 1.3;
finB = lum * 0.8;
}
newData[index] = finR;
newData[index + 1] = finG;
newData[index + 2] = finB;
newData[index + 3] = 255; // Alpha
}
}
// Repaint image with base effects
ctx.putImageData(new ImageData(newData, width, height), 0, 0);
// 5. Digital Glitch Rectangles Displacement
for (let i = 0; i < 40; i++) {
const gw = Math.random() * (width * 0.6) + 20;
const gh = Math.random() * 25 + 2;
const gx = Math.random() * width;
const gy = Math.random() * height;
const mShift = (Math.random() - 0.5) * 80;
ctx.drawImage(canvas, gx, gy, gw, gh, gx + mShift, gy, gw, gh);
}
// 6. Draw Scanlines
ctx.fillStyle = 'rgba(0, 0, 0, 0.4)';
for (let i = 0; i < height; i += 4) {
ctx.fillRect(0, i, width, 1.5);
}
// 7. Render Dark Cinematic Gradients (Vignetting for text legibility)
const gradTop = ctx.createLinearGradient(0, 0, 0, height * 0.3);
gradTop.addColorStop(0, 'rgba(0, 0, 0, 0.9)');
gradTop.addColorStop(1, 'rgba(0, 0, 0, 0)');
const gradBot = ctx.createLinearGradient(0, height * 0.5, 0, height);
gradBot.addColorStop(0, 'rgba(0, 0, 0, 0)');
gradBot.addColorStop(0.5, 'rgba(0, 0, 0, 0.7)');
gradBot.addColorStop(1, 'rgba(0, 0, 0, 0.95)');
const radialGrad = ctx.createRadialGradient(width / 2, height / 2, height * 0.2, width / 2, height / 2, height * 0.8);
radialGrad.addColorStop(0, 'rgba(0,0,0,0)');
radialGrad.addColorStop(1, 'rgba(0,0,0,0.6)');
ctx.fillStyle = gradTop; ctx.fillRect(0, 0, width, height);
ctx.fillStyle = gradBot; ctx.fillRect(0, 0, width, height);
ctx.fillStyle = radialGrad; ctx.fillRect(0, 0, width, height);
// 8. Add Static Noise (Overlay)
const noiseCanvas = document.createElement('canvas');
noiseCanvas.width = width;
noiseCanvas.height = height;
const noiseCtx = noiseCanvas.getContext('2d');
const noiseData = noiseCtx.createImageData(width, height);
for (let i = 0; i < noiseData.data.length; i += 4) {
const val = Math.random() * 255;
noiseData.data[i] = val;
noiseData.data[i + 1] = val;
noiseData.data[i + 2] = val;
noiseData.data[i + 3] = 25; // low opacity noise
}
noiseCtx.putImageData(noiseData, 0, 0);
ctx.globalCompositeOperation = 'overlay';
ctx.drawImage(noiseCanvas, 0, 0);
ctx.globalCompositeOperation = 'source-over';
// 9. Cyberpunk Frame Decorations
ctx.strokeStyle = 'rgba(0, 255, 204, 0.4)';
ctx.lineWidth = 1;
ctx.strokeRect(40, 40, width - 80, height - 80);
ctx.lineWidth = 5;
ctx.strokeStyle = 'rgba(255, 0, 60, 0.7)'; // Demonic red corners
const cLen = 30;
const inset = 37;
// Top-Left
ctx.beginPath(); ctx.moveTo(inset, inset + cLen); ctx.lineTo(inset, inset); ctx.lineTo(inset + cLen, inset); ctx.stroke();
// Top-Right
ctx.beginPath(); ctx.moveTo(width - inset, inset + cLen); ctx.lineTo(width - inset, inset); ctx.lineTo(width - inset - cLen, inset); ctx.stroke();
// Bottom-Left
ctx.beginPath(); ctx.moveTo(inset, height - inset - cLen); ctx.lineTo(inset, height - inset); ctx.lineTo(inset + cLen, height - inset); ctx.stroke();
// Bottom-Right
ctx.beginPath(); ctx.moveTo(width - inset, height - inset - cLen); ctx.lineTo(width - inset, height - inset); ctx.lineTo(width - inset - cLen, height - inset); ctx.stroke();
// 10. Draw Texts
const drawGlitchText = (text, x, y, size, font, primaryCol, shiftAmt) => {
ctx.font = `${size}px "${font}", sans-serif`;
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
// Chromatic split
ctx.fillStyle = 'rgba(0, 255, 255, 0.75)';
ctx.fillText(text, x - shiftAmt, y);
ctx.fillStyle = 'rgba(255, 0, 60, 0.75)';
ctx.fillText(text, x + shiftAmt, y);
ctx.fillStyle = primaryCol;
ctx.fillText(text, x, y);
};
// Calculate responsive title font size
let titleSize = 100;
ctx.font = `${titleSize}px "Rubik Glitch", sans-serif`;
if ('letterSpacing' in ctx) ctx.letterSpacing = '5px';
// Scale title down if needed
while (ctx.measureText(title).width > width - 100 && titleSize > 30) {
titleSize -= 3;
ctx.font = `${titleSize}px "Rubik Glitch", sans-serif`;
}
// Render Title
drawGlitchText(title, width / 2, height * 0.82, titleSize, 'Rubik Glitch', '#ffffff', 4);
// Reset letterspacing for other texts
if ('letterSpacing' in ctx) ctx.letterSpacing = '10px';
// Render Tagline
drawGlitchText(tagline, width / 2, height * 0.12, 22, 'Share Tech Mono', '#00ffcc', 2);
// Render Release Date
drawGlitchText(releaseDate, width / 2, height * 0.92, 28, 'Share Tech Mono', '#ff003c', 2);
// Some extra cyberpunk decorative text
if ('letterSpacing' in ctx) ctx.letterSpacing = '0px';
ctx.fillStyle = 'rgba(255, 255, 255, 0.4)';
ctx.font = `12px "Share Tech Mono", monospace`;
ctx.fillText("WARN: PARANORMAL ALGORITHM DETECTED", width / 2, height * 0.16);
ctx.textAlign = 'left';
ctx.fillText("v2027.0.51", 45, 55);
ctx.textAlign = 'right';
ctx.fillText("ERR_404_SOUL_NOT_FOUND", width - 45, 55);
return canvas;
}
Apply Changes