Please bookmark this page to avoid losing your image tool!

Image Character Window Tool

(Free & Supports Bulk Upload)

Drag & drop your images here or

The result will appear here...
You can edit the below JavaScript code to customize the image tool.
async function processImage(originalImg, windowTitle = 'Character Info', windowColor = '#0055A4', borderColor = '#C0C0C0', textColor = '#FFFFFF') {

    /**
     * Dynamically loads the "Press Start 2P" font from Google Fonts.
     * This is an async operation that waits until the font is ready for use.
     */
    const loadFont = async () => {
        const font = '16px "Press Start 2P"';
        // Avoid reloading the font if it's already available.
        if (document.fonts.check(font)) {
            return;
        }

        try {
            const fontLink = document.createElement('link');
            fontLink.href = 'https://fonts.googleapis.com/css2?family=Press+Start+2P&display=swap';
            fontLink.rel = 'stylesheet';
            document.head.appendChild(fontLink);

            // Wait for the stylesheet to load, then for the font to be available in the document.
            await new Promise(resolve => fontLink.onload = resolve);
            await document.fonts.load(font);
        } catch (e) {
            console.error("Could not load Google Font. Using a fallback font.", e);
        }
    };

    /**
     * Adjusts a hex color by a given percentage.
     * @param {string} hex The hex color string (e.g., "#0055A4").
     * @param {number} percent The percentage to lighten or darken (e.g., 20 for lighter, -20 for darker).
     * @returns {string} The adjusted hex color string.
     */
    const adjustColor = (hex, percent) => {
        const f = parseInt(hex.slice(1), 16);
        const t = percent < 0 ? 0 : 255;
        const p = percent < 0 ? percent * -1 : percent;
        const R = f >> 16;
        const G = (f >> 8) & 0x00FF;
        const B = f & 0x0000FF;
        const newR = Math.round((t - R) * (p / 100)) + R;
        const newG = Math.round((t - G) * (p / 100)) + G;
        const newB = Math.round((t - B) * (p / 100)) + B;
        return `#${(0x1000000 + newR * 0x10000 + newG * 0x100 + newB).toString(16).slice(1)}`;
    };

    /**
     * Draws a rectangle with rounded corners.
     */
    const drawRoundedRect = (ctx, x, y, width, height, radius) => {
        ctx.beginPath();
        ctx.moveTo(x + radius, y);
        ctx.lineTo(x + width - radius, y);
        ctx.arcTo(x + width, y, x + width, y + radius, radius);
        ctx.lineTo(x + width, y + height - radius);
        ctx.arcTo(x + width, y + height, x + width - radius, y + height, radius);
        ctx.lineTo(x + radius, y + height);
        ctx.arcTo(x, y + height, x, y + height - radius, radius);
        ctx.lineTo(x, y + radius);
        ctx.arcTo(x, y, x + radius, y, radius);
        ctx.closePath();
    };

    // --- Main execution starts here ---

    // 1. Ensure the required font is loaded before drawing.
    await loadFont();

    // 2. Define layout constants.
    const padding = 10;
    const titleHeight = 30;
    const borderWidth = 2;
    const cornerRadius = 8;
    const imagePadding = 8;

    // 3. Create canvas and set its dimensions.
    const canvas = document.createElement('canvas');
    canvas.width = originalImg.width + (padding + borderWidth + imagePadding) * 2;
    canvas.height = originalImg.height + (padding + borderWidth + imagePadding) * 2 + titleHeight;
    const ctx = canvas.getContext('2d');

    // 4. Draw the outer border/background.
    ctx.fillStyle = borderColor;
    drawRoundedRect(ctx, 0, 0, canvas.width, canvas.height, cornerRadius);
    ctx.fill();

    // 5. Draw the main window panel.
    ctx.fillStyle = windowColor;
    drawRoundedRect(ctx, borderWidth, borderWidth, canvas.width - borderWidth * 2, canvas.height - borderWidth * 2, cornerRadius - 1);
    ctx.fill();

    // 6. Draw a 3D bevel effect for a retro UI look.
    const lighterColor = adjustColor(windowColor, 20);
    const darkerColor = adjustColor(windowColor, -20);
    const innerX = borderWidth + padding;
    const innerY = borderWidth + padding;
    const innerWidth = canvas.width - (borderWidth + padding) * 2;
    const innerHeight = canvas.height - (borderWidth + padding) * 2;

    // Lighter edges (top and left)
    ctx.strokeStyle = lighterColor;
    ctx.lineWidth = 2;
    ctx.beginPath();
    ctx.moveTo(innerX, innerY + innerHeight);
    ctx.lineTo(innerX, innerY);
    ctx.lineTo(innerX + innerWidth, innerY);
    ctx.stroke();

    // Darker edges (bottom and right)
    ctx.strokeStyle = darkerColor;
    ctx.beginPath();
    ctx.moveTo(innerX, innerY + innerHeight);
    ctx.lineTo(innerX + innerWidth, innerY + innerHeight);
    ctx.lineTo(innerX + innerWidth, innerY);
    ctx.stroke();

    // 7. Draw the window title.
    ctx.fillStyle = textColor;
    ctx.font = '16px "Press Start 2P", monospace';
    ctx.textAlign = 'center';
    ctx.textBaseline = 'middle';
    const titleX = canvas.width / 2;
    const titleY = borderWidth + padding + (titleHeight / 2);
    // Add a slight shadow for readability
    ctx.fillStyle = 'rgba(0, 0, 0, 0.5)';
    ctx.fillText(windowTitle, titleX + 1, titleY + 1);
    // Draw the main text
    ctx.fillStyle = textColor;
    ctx.fillText(windowTitle, titleX, titleY);

    // 8. Draw the character image inside the window.
    const imageX = borderWidth + padding + imagePadding;
    const imageY = borderWidth + padding + titleHeight + imagePadding;
    ctx.drawImage(originalImg, imageX, imageY);

    return canvas;
}

Free Image Tool Creator

Can't find the image tool you're looking for?
Create one based on your own needs now!

Description

The Image Character Window Tool allows users to create a visually appealing display of an image, framed within a stylized window interface that includes a title and customizable colors. This tool can be useful for presenting character designs, illustrations, or any other images in a unique format, making it ideal for game developers, artists, and content creators looking to enhance their visual presentations.

Leave a Reply

Your email address will not be published. Required fields are marked *