Image Tourism Poster Creator For ‘Visit [Location]’
(Free & Supports Bulk Upload)
The result will appear here...
JavaScript Code (For Advanced Users)
You can edit the below JavaScript code to customize the image tool.
async function processImage(originalImg, locationName = "DreamLand", textColor = "white", fontName = "Impact", fontSize = 72, textPosition = "bottom-center", strokeColor = "black", strokeWidth = 3) {
// Helper function to get a generic CSS font family based on a specific font name's characteristics
function _getSystemGeneric(fontNameStr) {
if (!fontNameStr || typeof fontNameStr !== 'string') return "sans-serif";
const lcFontName = fontNameStr.toLowerCase();
if (lcFontName.includes("times") || lcFontName.includes("georgia") || lcFontName.includes("garamond") || lcFontName.includes("palatino") || (lcFontName.includes("serif") && !lcFontName.includes("sans-serif"))) return "serif";
if (lcFontName.includes("courier") || lcFontName.includes("consolas") || lcFontName.includes("monaco") || lcFontName.includes("mono")) return "monospace";
if (lcFontName.includes("cursive") || lcFontName.includes("zapfino") || lcFontName.includes("comic sans")) return "cursive"; // comic sans is often debated, but fits cursive category for some uses
if (lcFontName.includes("fantasy") || lcFontName.includes("papyrus")) return "fantasy";
// Default fallback for Arial, Helvetica, Verdana, Impact, Open Sans etc.
return "sans-serif";
}
// Helper function to attempt to load a font, especially from Google Fonts CDN
async function _ensureFontIsLoadedInternal(requestedFontFamily, fallbackFontFamily) {
const webSafeFonts = [
"arial", "helvetica", "times new roman", "times", "courier new", "courier",
"verdana", "georgia", "palatino", "garamond", "tahoma", "impact", "comic sans ms",
"sans-serif", "serif", "monospace", "cursive", "fantasy" // CSS generic families
];
if (webSafeFonts.includes(requestedFontFamily.toLowerCase())) {
return requestedFontFamily; // Already web-safe or generic, no loading needed
}
// Use Font Loading API if available
if (document.fonts) {
try {
// Heuristic: if font name looks like a typical Google Font name, try to add its stylesheet.
// This allows document.fonts.load to find non-standard fonts if they are on Google Fonts.
// Regex matches typical Google Font naming: capitalized words, optionally with spaces. Examples: "Roboto", "Open Sans", "Noto Sans JP"
const looksLikeGoogleFont = /^[A-Z][a-zA-Z0-9]*(?:\s[A-Z][a-zA-Z0-9]*)*$/.test(requestedFontFamily);
if (looksLikeGoogleFont) {
const familyId = requestedFontFamily.replace(/\s+/g, '+');
const fontCssUrl = `https://fonts.googleapis.com/css2?family=${familyId}:wght@400&display=swap`; // Regular weight
const styleId = `google-font-stylesheet-${familyId.replace(/[+ ]/g, '-')}`; // Create a DOM-safe ID
if (!document.getElementById(styleId)) {
try {
await new Promise((resolve, reject) => {
const link = document.createElement('link');
link.id = styleId;
link.rel = 'stylesheet';
link.href = fontCssUrl;
link.onload = resolve;
link.onerror = (err) => {
// console.warn(`Stylesheet for ${requestedFontFamily} failed to load from ${fontCssUrl}.`);
reject(new Error(`Stylesheet load error for ${requestedFontFamily}`));
};
document.head.appendChild(link);
});
} catch (e) {
// console.warn(e.message);
// If stylesheet fails to load, document.fonts.load will likely also fail for this font,
// unless it's defined elsewhere (e.g. system font, or other CSS).
}
}
}
// Attempt to load the font. This will wait if a stylesheet (e.g. Google Fonts) is still loading.
// It can also load system fonts not in the web-safe list if the browser supports it.
await document.fonts.load(`1em "${requestedFontFamily}"`);
return requestedFontFamily; // Font successfully loaded or made available
} catch (error) {
// console.warn(`Failed to load font "${requestedFontFamily}" using document.fonts.load API. Error: ${error}. Using fallback "${fallbackFontFamily}".`);
return fallbackFontFamily; // Fallback if any error in loading
}
} else {
// Fallback for browsers without Font Loading API (e.g. older browsers)
// console.warn("document.fonts API not available. Font loading for non-web-safe fonts relies on browser's @font-face handling (if CSS is pre-loaded or added).");
// Try to add Google Font stylesheet if it looks like one (fire and forget)
const looksLikeGoogleFont = /^[A-Z][a-zA-Z0-9]*(?:\s[A-Z][a-zA-Z0-9]*)*$/.test(requestedFontFamily);
if (looksLikeGoogleFont) {
const familyId = requestedFontFamily.replace(/\s+/g, '+');
const fontCssUrl = `https://fonts.googleapis.com/css2?family=${familyId}:wght@400&display=swap`;
const styleId = `google-font-stylesheet-${familyId.replace(/[+ ]/g, '-')}`;
if (!document.getElementById(styleId)) {
const link = document.createElement('link');
link.id = styleId;
link.rel = 'stylesheet';
link.href = fontCssUrl;
document.head.appendChild(link);
}
}
// Cannot reliably wait for font loading here. Return requested font and hope browser finds it.
return requestedFontFamily;
}
}
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
const imgWidth = originalImg.naturalWidth || originalImg.width;
const imgHeight = originalImg.naturalHeight || originalImg.height;
if (imgWidth === 0 || imgHeight === 0) {
console.error("Image has no dimensions or has not loaded yet. Cannot create poster.");
// Create a fallback canvas indicating the error
canvas.width = 300;
canvas.height = 100;
ctx.fillStyle = '#F0F0F0';
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = '#A0A0A0';
ctx.font = 'bold 16px Arial';
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.fillText("Error: Image not loaded/sized.", canvas.width / 2, canvas.height / 2);
return canvas;
}
canvas.width = imgWidth;
canvas.height = imgHeight;
ctx.drawImage(originalImg, 0, 0, canvas.width, canvas.height);
const ultimateFallbackFont = "Arial"; // A truly common font
const loadedFontName = await _ensureFontIsLoadedInternal(fontName, ultimateFallbackFont);
const finalFontCssString = `"${loadedFontName}", ${_getSystemGeneric(loadedFontName)}`;
const text = "Visit " + locationName;
const currentFontSize = Number(fontSize); // Ensure numeric type
ctx.font = `${currentFontSize}px ${finalFontCssString}`;
ctx.fillStyle = textColor;
ctx.textAlign = "center";
ctx.textBaseline = "middle"; // Vertically center text at y coordinate
let x, y;
// Calculate padding based on font size to avoid text touching edges
const padding = currentFontSize * 0.4;
switch (textPosition.toLowerCase()) {
case "top-center":
x = canvas.width / 2;
y = (currentFontSize / 2) + padding; // Center of text from top
break;
case "middle-center":
x = canvas.width / 2;
y = canvas.height / 2;
break;
case "bottom-center":
default:
x = canvas.width / 2;
y = canvas.height - (currentFontSize / 2) - padding; // Center of text from bottom
break;
}
const currentStrokeWidth = Number(strokeWidth); // Ensure numeric type
if (currentStrokeWidth > 0 && strokeColor && strokeColor.toLowerCase() !== "transparent" && strokeColor.toLowerCase() !== "none") {
ctx.strokeStyle = strokeColor;
ctx.lineWidth = currentStrokeWidth;
ctx.strokeText(text, x, y);
}
ctx.fillText(text, x, y);
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 Tourism Poster Creator for Visit [Location]’ is a tool that allows users to create visually appealing tourism posters by overlaying customized text on images. Users can specify the location name, text color, font name, font size, text position, stroke color, and stroke width to personalize their posters. This tool is ideal for travel bloggers, marketing professionals, and anyone looking to promote tourism in specific locations by creating eye-catching promotional materials.