You can edit the below JavaScript code to customize the image tool.
async function processImage(
originalImg,
titleText = "THE UNKNOWN",
taglineText = "Fear has a new name.",
titleFontFamily = "Creepster, Impact, fantasy", // CSS font-family string
titleColor = "#B90000", // A typical horror red
titleSizeRatio = 0.15, // Relative to canvas height for font size
taglineFontFamily = "Georgia, 'Times New Roman', serif",
taglineColor = "#E0E0E0", // Off-white for tagline
taglineSizeRatio = 0.04, // Relative to canvas height
imageOverlayColor = "rgba(30, 0, 0, 0.7)", // Dark, reddish overlay
textShadowColor = "rgba(0, 0, 0, 0.8)",
textShadowBlur = 10 // Px blur for shadow
) {
// Inner helper function to load web fonts
async function _loadWebFont(fontFamilyCssString) {
// Extract the primary font name (the first one in the CSS string)
const primaryFontName = fontFamilyCssString.split(',')[0].trim().replace(/['"]/g, '');
if (!primaryFontName) return;
// Predefined map of known web fonts and their CDN URLs
const knownWebFonts = {
'Creepster': 'https://fonts.gstatic.com/s/creepster/v23/AlZy_zVUqJz4yMrniH4hdXKyPA.woff2',
// Example: 'Nosifier': 'https://fonts.gstatic.com/s/nosifier/v22/ga6yaxBOxytNWAYyKMyIPb47kQ.woff2',
};
if (knownWebFonts[primaryFontName]) {
const fontUrl = knownWebFonts[primaryFontName];
const styleId = `font-style-${primaryFontName.replace(/\s+/g, '-')}`;
// If style tag already exists, assume font is loading or loaded.
// We still need to wait for it if document.fonts API is available.
if (document.getElementById(styleId)) {
if (document.fonts) {
try {
// Wait for the font to be usable
await document.fonts.load(`12px "${primaryFontName}"`);
} catch (e) {
console.warn(`Error waiting for already-declared font ${primaryFontName}:`, e);
}
}
return;
}
// If document.fonts API is available, check if font is already globally available
// (e.g., system font, or loaded by other means previously)
if (document.fonts && document.fonts.check(`12px "${primaryFontName}"`)) {
return;
}
const style = document.createElement('style');
style.id = styleId;
style.textContent = `
@font-face {
font-family: "${primaryFontName}";
src: url('${fontUrl}') format('woff2');
font-display: swap; /* Recommended for web use, though less critical for canvas if we await load */
}
`;
document.head.appendChild(style);
if (document.fonts) {
try {
await document.fonts.load(`12px "${primaryFontName}"`);
} catch (e) {
console.warn(`Failed to load font ${primaryFontName} from ${fontUrl}:`, e);
// Clean up the added style tag if font loading fails
const el = document.getElementById(styleId);
if (el) el.parentNode.removeChild(el);
}
} else {
// Fallback for older browsers without document.fonts API
// The font will load, but we can't easily wait for it.
// Canvas drawing might use a fallback font initially.
console.warn("document.fonts API not available. Font rendering may be delayed or use fallbacks for non-standard fonts.");
}
}
}
// Load necessary fonts specified in parameters
// The _loadWebFont helper will only attempt to load if the primary font is in its known list.
await _loadWebFont(titleFontFamily);
await _loadWebFont(taglineFontFamily);
const canvas = document.createElement('canvas');
// Ensure originalImg is loaded and has dimensions
if (!originalImg || originalImg.naturalWidth === 0 || originalImg.naturalHeight === 0) {
console.error("Original image is not loaded or has zero dimensions.");
// Create a fallback canvas indicating the error
canvas.width = 600;
canvas.height = 900; // Typical poster aspect ratio
const errorCtx = canvas.getContext('2d');
errorCtx.fillStyle = '#333333';
errorCtx.fillRect(0,0,canvas.width, canvas.height);
errorCtx.fillStyle = 'white';
errorCtx.font = '24px Arial';
errorCtx.textAlign = 'center';
errorCtx.textBaseline = 'middle';
errorCtx.fillText('Error: Image not loaded correctly.', canvas.width/2, canvas.height/2);
return canvas;
}
canvas.width = originalImg.naturalWidth;
canvas.height = originalImg.naturalHeight;
const ctx = canvas.getContext('2d');
// 1. Draw the original image
ctx.drawImage(originalImg, 0, 0, canvas.width, canvas.height);
// 2. Apply image overlay color for mood
if (imageOverlayColor && imageOverlayColor !== 'transparent') {
ctx.fillStyle = imageOverlayColor;
ctx.fillRect(0, 0, canvas.width, canvas.height);
}
// Common text settings for shadow
ctx.textAlign = 'center';
if (textShadowBlur > 0 && textShadowColor && textShadowColor !== 'transparent') {
ctx.shadowColor = textShadowColor;
ctx.shadowBlur = textShadowBlur;
// Dynamic shadow offset based on blur for a bit more depth
// Ensure offset is at least 1px if blur is active for visibility.
ctx.shadowOffsetX = Math.max(1, Math.floor(textShadowBlur / 4));
ctx.shadowOffsetY = Math.max(1, Math.floor(textShadowBlur / 4));
}
// 3. Draw Title Text (usually large and prominent)
if (titleText) {
const titleActualFontSize = Math.max(10, Math.floor(canvas.height * titleSizeRatio));
ctx.font = `${titleActualFontSize}px ${titleFontFamily}`;
ctx.fillStyle = titleColor;
ctx.textBaseline = 'top';
// Position title towards the top, with some margin
const titleY = canvas.height * 0.08;
ctx.fillText(titleText.toUpperCase(), canvas.width / 2, titleY);
}
// 4. Draw Tagline Text (smaller, often below title or near bottom)
if (taglineText) {
const taglineActualFontSize = Math.max(8, Math.floor(canvas.height * taglineSizeRatio));
ctx.font = `${taglineActualFontSize}px ${taglineFontFamily}`;
ctx.fillStyle = taglineColor;
ctx.textBaseline = 'bottom';
// Position tagline towards the bottom, with some margin
const taglineY = canvas.height * 0.92;
ctx.fillText(taglineText, canvas.width / 2, taglineY);
}
// Reset shadow settings to avoid affecting other drawings if canvas context is used further (good practice)
ctx.shadowColor = 'transparent';
ctx.shadowBlur = 0;
ctx.shadowOffsetX = 0;
ctx.shadowOffsetY = 0;
return canvas;
}
Free Image Tool Creator
Can't find the image tool you're looking for? Create one based on your own needs now!
The Image Horror Movie Poster Template tool allows users to create custom horror-themed movie posters by overlaying text and effects on an original image. With options to customize the title, tagline, font types, colors, and overlay effects, users can easily produce eye-catching posters suitable for various creative purposes, such as film promotions, personal projects, or graphic design exercises. This tool is especially useful for filmmakers, artists, or any enthusiasts looking to evoke a sense of horror and intrigue in their visuals.