You can edit the below JavaScript code to customize the image tool.
Apply Changes
async function processImage(originalImg, vintageEffect = 0.4, blurAmount = 0.5, grainAmount = 0.15, vignetteAmount = 0.5, text = 'Союзмультфильм', textColor = '#F5DEB3', textSize = 40) {
// 1. Setup Canvas
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
// Make canvas responsive to image size
const imgWidth = originalImg.naturalWidth;
const imgHeight = originalImg.naturalHeight;
canvas.width = imgWidth;
canvas.height = imgHeight;
// 2. Apply Base Vintage Filters
// These filters give the image a warm, slightly blurred, aged look.
ctx.filter = `sepia(${vintageEffect}) brightness(${1 - vintageEffect * 0.2}) contrast(${1 + vintageEffect * 0.1}) blur(${blurAmount}px)`;
ctx.drawImage(originalImg, 0, 0, imgWidth, imgHeight);
ctx.filter = 'none'; // Reset filter for subsequent operations
// 3. Add Film Grain
if (grainAmount > 0) {
const imageData = ctx.getImageData(0, 0, imgWidth, imgHeight);
const data = imageData.data;
const grainStrength = 255 * grainAmount;
for (let i = 0; i < data.length; i += 4) {
// Add a random noise value to R, G, and B channels
const noise = (Math.random() - 0.5) * grainStrength;
data[i] = Math.max(0, Math.min(255, data[i] + noise));
data[i + 1] = Math.max(0, Math.min(255, data[i + 1] + noise));
data[i + 2] = Math.max(0, Math.min(255, data[i + 2] + noise));
// Alpha channel (data[i + 3]) is left untouched
}
ctx.putImageData(imageData, 0, 0);
}
// 4. Add Vignette Effect
// This darkens the corners, mimicking old camera lenses.
if (vignetteAmount > 0) {
const centerX = imgWidth / 2;
const centerY = imgHeight / 2;
const outerRadius = Math.sqrt(centerX * centerX + centerY * centerY);
const gradient = ctx.createRadialGradient(
centerX, centerY, outerRadius * (1 - vignetteAmount),
centerX, centerY, outerRadius
);
gradient.addColorStop(0, 'rgba(0,0,0,0)');
gradient.addColorStop(1, `rgba(0,0,0,${Math.min(1, vignetteAmount * 0.8)})`);
ctx.fillStyle = gradient;
ctx.fillRect(0, 0, imgWidth, imgHeight);
}
// 5. Add Text Overlay
if (text && text.trim() !== '') {
const fontName = 'Marck Script';
const fontUrl = `https://fonts.googleapis.com/css2?family=${fontName.replace(' ', '+')}&display=swap`;
// Dynamically load the Google Font if it hasn't been loaded yet
if (!document.getElementById('google-font-soyuzmultfilm')) {
const link = document.createElement('link');
link.id = 'google-font-soyuzmultfilm';
link.rel = 'stylesheet';
link.href = fontUrl;
document.head.appendChild(link);
// Wait for the font to be loaded and ready to use
await document.fonts.load(`${textSize}px "${fontName}"`);
}
const dynamicTextSize = Math.max(20, Math.min(imgWidth / 15, textSize));
ctx.font = `bold ${dynamicTextSize}px "${fontName}"`;
ctx.fillStyle = textColor;
ctx.textAlign = 'right';
ctx.textBaseline = 'bottom';
// Add a subtle shadow for better readability
ctx.shadowColor = 'rgba(0, 0, 0, 0.7)';
ctx.shadowBlur = 5;
ctx.shadowOffsetX = 2;
ctx.shadowOffsetY = 2;
const padding = dynamicTextSize * 0.5;
ctx.fillText(text, imgWidth - padding, imgHeight - padding);
// Reset shadow for any future drawing
ctx.shadowColor = 'transparent';
ctx.shadowBlur = 0;
ctx.shadowOffsetX = 0;
ctx.shadowOffsetY = 0;
}
// 6. Return the final canvas
return canvas;
}
Apply Changes