You can edit the below JavaScript code to customize the image tool.
async function processImage(originalImg, text = 'День кино', textColor = '#F5DEB3', fontSize = 60, effectType = 'vintage') {
/**
* Dynamically loads a Google Font into the document.
* Caches the <link> tag to avoid re-adding it on subsequent calls.
* @param {string} fontFamily - The name of the font family.
* @param {string} weight - The font weight to load.
* @returns {Promise<void>} A promise that resolves when the font is ready to be used.
*/
const loadGoogleFont = async (fontFamily, weight) => {
const fontId = `font-${fontFamily.replace(/\s+/g, '-')}-${weight}`;
// Don't re-add the <link> element if it already exists
if (!document.getElementById(fontId)) {
const link = document.createElement('link');
link.id = fontId;
link.rel = 'stylesheet';
link.href = `https://fonts.googleapis.com/css2?family=${fontFamily.replace(/\s+/g, '+')}:wght@${weight}&display=swap`;
document.head.appendChild(link);
// Wait for the stylesheet to load before trying to use the font
await new Promise((resolve, reject) => {
link.onload = resolve;
link.onerror = reject;
}).catch(e => {
console.error("Could not load font stylesheet.", e);
throw e; // Propagate error for the caller to handle
});
}
// Wait for the font to be downloaded and ready to use by the browser
await document.fonts.load(`${weight} 1em "${fontFamily}"`);
};
// 1. Load the required font for the cinematic text
const FONT_FAMILY = 'Oswald';
const FONT_WEIGHT = '700';
try {
await loadGoogleFont(FONT_FAMILY, FONT_WEIGHT);
} catch (e) {
console.error(`Font "${FONT_FAMILY}" failed to load, falling back to sans-serif.`, e);
}
// 2. Set up canvas dimensions
const imgWidth = originalImg.width;
const imgHeight = originalImg.height;
// The filmstrip border height is proportional to the image width for a consistent look
const borderHeight = imgWidth * 0.08;
const canvas = document.createElement('canvas');
canvas.width = imgWidth;
canvas.height = imgHeight + 2 * borderHeight;
const ctx = canvas.getContext('2d');
// 3. Draw the filmstrip frame
// Background color for the entire canvas (serves as the border color)
ctx.fillStyle = '#111111';
ctx.fillRect(0, 0, canvas.width, canvas.height);
// Function to draw sprocket holes on the filmstrip borders
const drawSprockets = (y) => {
const holeHeight = borderHeight * 0.4;
const holeWidth = holeHeight * 1.5;
const holeSpacing = holeWidth * 1.8;
ctx.fillStyle = '#DDDDDD';
for (let x = holeSpacing / 2; x < canvas.width; x += holeSpacing) {
ctx.fillRect(x - holeWidth / 2, y - holeHeight / 2, holeWidth, holeHeight);
}
};
drawSprockets(borderHeight / 2); // Top border
drawSprockets(canvas.height - borderHeight / 2); // Bottom border
// 4. Draw the original image with the selected filter
ctx.save(); // Save context state before applying filters
switch (effectType.toLowerCase()) {
case 'vintage':
ctx.filter = 'sepia(0.7) contrast(1.1) brightness(0.9) saturate(1.2)';
break;
case 'b&w':
ctx.filter = 'grayscale(1) contrast(1.2) brightness(0.9)';
break;
case 'none': // Explicitly handle 'none'
default:
// No filter is applied for 'none' or any unknown effect types
break;
}
ctx.drawImage(originalImg, 0, borderHeight, imgWidth, imgHeight);
ctx.restore(); // Restore context to remove the filter for subsequent drawings
// 5. Apply a classic vignette effect over the image area
const centerX = imgWidth / 2;
const centerY = borderHeight + imgHeight / 2;
// Calculate radius to fully cover the image area from corner to corner
const outerRadius = Math.sqrt(Math.pow(imgWidth / 2, 2) + Math.pow(imgHeight / 2, 2));
const innerRadius = outerRadius * 0.3; // The inner, fully transparent area
const gradient = ctx.createRadialGradient(centerX, centerY, innerRadius, centerX, centerY, outerRadius);
gradient.addColorStop(0, 'rgba(0,0,0,0)');
gradient.addColorStop(1, 'rgba(0,0,0,0.65)');
ctx.fillStyle = gradient;
ctx.fillRect(0, borderHeight, imgWidth, imgHeight);
// 6. Draw the text on the bottom filmstrip border
// The font size is a percentage of the border's height, making it responsive
const finalFontSize = borderHeight * (fontSize / 100);
ctx.font = `${FONT_WEIGHT} ${finalFontSize}px "${FONT_FAMILY}", sans-serif`;
ctx.fillStyle = textColor;
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
// Add a subtle shadow to make the text pop
ctx.shadowColor = 'rgba(0, 0, 0, 0.8)';
ctx.shadowBlur = 5;
ctx.shadowOffsetX = 1;
ctx.shadowOffsetY = 1;
// Position text in the vertical middle of the bottom border
ctx.fillText(text.toUpperCase(), canvas.width / 2, canvas.height - borderHeight / 2);
// Reset shadow to avoid affecting any potential future drawings (good practice)
ctx.shadowColor = 'transparent';
ctx.shadowBlur = 0;
ctx.shadowOffsetX = 0;
ctx.shadowOffsetY = 0;
// 7. Return the completed canvas element
return canvas;
}
Free Image Tool Creator
Can't find the image tool you're looking for? Create one based on your own needs now!
Image Celebration of Cinema is an online tool that enables users to transform their images into artistic representations inspired by classic cinema. By applying vintage or black-and-white effects, adding a filmstrip border, and including custom text, this tool is perfect for movie lovers looking to create unique posters or social media graphics. The tool can be used for personal projects, event promotions, or as a creative way to celebrate film-related occasions.