Please bookmark this page to avoid losing your image tool!

Image One Piece Wanted Poster Creator

(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, name = "MONKEY D. LUFFY", bounty = "3000000000", titleText = "WANTED", subtitleText = "DEAD OR ALIVE", marineText = "MARINE") {

    const canvas = document.createElement('canvas');
    const ctx = canvas.getContext('2d');

    // --- Configuration ---
    const canvasWidth = 600;
    const canvasHeight = 850;

    const posterBackgroundColor = '#F5E8C7'; // Parchment like
    const posterBorderColor = '#654321';   // Dark brown
    const textPrimaryColor = '#3A241D';    // Very dark brown for titles
    const textSecondaryColor = 'black';    // For name, bounty
    const imageBorderColor = '#3A241D';

    // --- Setup Canvas ---
    canvas.width = canvasWidth;
    canvas.height = canvasHeight;

    // --- Helper to load Google Fonts ---
    const loadGoogleFont = async (fontFamily, fontWeight = '400') => {
        const fontCss = fontFamily.replace(/\s+/g, '+');
        const fontUrl = `https://fonts.googleapis.com/css2?family=${fontCss}:wght@${fontWeight}&display=swap`;

        let linkExists = false;
        document.querySelectorAll('link[rel="stylesheet"]').forEach(link => {
            if (link.href === fontUrl) {
                linkExists = true;
            }
        });

        if (!linkExists) {
            const link = document.createElement('link');
            link.rel = 'stylesheet';
            link.href = fontUrl;
            document.head.appendChild(link);
            await new Promise((resolve, reject) => {
                link.onload = resolve;
                link.onerror = (err) => {
                    console.error(`Failed to load stylesheet: ${fontUrl}`, err);
                    reject(new Error(`Stylesheet load error for ${fontFamily}`));
                };
            });
        }
        try {
            await document.fonts.load(`${fontWeight} 1em "${fontFamily}"`);
        } catch (err) {
            console.error(`Failed to load font: ${fontFamily} (weight ${fontWeight})`, err);
            throw new Error(`Font load error for ${fontFamily}`);
        }
    };

    // --- Load Fonts ---
    try {
        await Promise.all([
            loadGoogleFont('Luckiest Guy', '400'),
            loadGoogleFont('Pirata One', '400')
        ]);
    } catch (error) {
        console.error("Font loading failed:", error);
        // Basic fallback: a message on canvas or using system fonts (though this might not look good)
        ctx.fillStyle = 'red';
        ctx.font = '20px sans-serif';
        ctx.textAlign = 'center';
        ctx.fillText('Error: Fonts could not be loaded.', canvasWidth / 2, canvasHeight / 2);
        return canvas; // Return canvas with error message
    }
    
    // --- Ensure originalImg is loaded ---
    if (!originalImg.complete || originalImg.naturalWidth === 0) {
        try {
            await new Promise((resolve, reject) => {
                // If src is already set and image is loading/failed, these handlers should catch it.
                // If src not set, this won't help. Caller must provide a valid Image object with src.
                if (originalImg.src) { // Only if src is set
                    const oldOnload = originalImg.onload;
                    const oldOnerror = originalImg.onerror;
                    originalImg.onload = () => { oldOnload?.(); resolve(); };
                    originalImg.onerror = (e) => { oldOnerror?.(); reject(new Error("Original image failed to load")); };
                    // If already failed and onerror was called, above might not re-trigger.
                    // If src is set and it fails after this point, it will be caught.
                    // This relies on the Image object being properly handled before passing.
                    // A common case is just checking .complete again if it wasn't at first.
                    if(originalImg.complete && originalImg.naturalWidth !== 0) resolve();
                } else {
                     reject(new Error("Original image has no src."));
                }
            });
        } catch (e) {
            console.error("Error with input image:", e.message);
            ctx.fillStyle = 'red';
            ctx.font = '20px sans-serif';
            ctx.textAlign = 'center';
            ctx.fillText('Error: Input image invalid.', canvasWidth / 2, canvasHeight / 2 + 30);
            return canvas;
        }
    }


    // --- Draw Background ---
    ctx.fillStyle = posterBackgroundColor;
    ctx.fillRect(0, 0, canvasWidth, canvasHeight);

    // --- Draw Main Border ---
    ctx.strokeStyle = posterBorderColor;
    ctx.lineWidth = 10; // Defines the thickness of the border
    ctx.strokeRect(ctx.lineWidth / 2, ctx.lineWidth / 2, canvasWidth - ctx.lineWidth, canvasHeight - ctx.lineWidth);

    // --- Draw "WANTED" Text ---
    ctx.font = '90px "Luckiest Guy"';
    ctx.fillStyle = textPrimaryColor;
    ctx.textAlign = 'center';
    ctx.shadowColor = 'rgba(0,0,0,0.4)';
    ctx.shadowBlur = 4;
    ctx.shadowOffsetX = 3;
    ctx.shadowOffsetY = 3;
    ctx.fillText(titleText.toUpperCase(), canvasWidth / 2, 120);
    ctx.shadowColor = 'transparent'; // Reset shadow

    // --- Draw "DEAD OR ALIVE" Text ---
    ctx.font = '35px "Pirata One"';
    ctx.fillStyle = textPrimaryColor;
    ctx.fillText(subtitleText.toUpperCase(), canvasWidth / 2, 195);

    // --- Draw Image ---
    const imgContainerX = 60;
    const imgContainerY = 240;
    const imgContainerWidth = canvasWidth - 2 * imgContainerX; // 480px
    const imgContainerHeight = 300;

    let drawWidth = originalImg.width;
    let drawHeight = originalImg.height;
    const imgAspect = originalImg.width / originalImg.height;
    const containerAspect = imgContainerWidth / imgContainerHeight;

    if (drawWidth > imgContainerWidth || drawHeight > imgContainerHeight) {
        if (imgAspect > containerAspect) {
            drawWidth = imgContainerWidth;
            drawHeight = drawWidth / imgAspect;
        } else {
            drawHeight = imgContainerHeight;
            drawWidth = drawHeight * imgAspect;
        }
    }
    
    const dx = imgContainerX + (imgContainerWidth - drawWidth) / 2;
    const dy = imgContainerY + (imgContainerHeight - drawHeight) / 2;

    // Image border
    ctx.strokeStyle = imageBorderColor;
    ctx.lineWidth = 6;
    // Draw border slightly larger than image to frame it
    ctx.strokeRect(dx - (ctx.lineWidth/2), dy - (ctx.lineWidth/2), drawWidth + ctx.lineWidth, drawHeight + ctx.lineWidth);
    ctx.drawImage(originalImg, dx, dy, drawWidth, drawHeight);
    
    const imageBottomY = dy + drawHeight + (ctx.lineWidth/2); // Account for border visually pushing content down

    // --- Draw Name Text ---
    const nameY = imageBottomY + 70;
    ctx.font = '60px "Pirata One"';
    ctx.fillStyle = textSecondaryColor;
    ctx.shadowColor = 'rgba(0,0,0,0.3)';
    ctx.shadowBlur = 3;
    ctx.shadowOffsetX = 2;
    ctx.shadowOffsetY = 2;
    ctx.fillText(name.toUpperCase(), canvasWidth / 2, nameY);
    ctx.shadowColor = 'transparent'; // Reset shadow

    // --- Draw Bounty Text ---
    const bountyY = nameY + 70;
    const numericBounty = Number(String(bounty).replace(/,/g, ''));
    const bountyString = isNaN(numericBounty) ? String(bounty) : numericBounty.toLocaleString('en-US');
    const formattedBounty = '฿' + bountyString + '-';
    
    ctx.font = '50px "Pirata One"';
    ctx.fillStyle = textSecondaryColor;
    ctx.fillText(formattedBounty, canvasWidth / 2, bountyY);

    // --- Draw "MARINE" Text ---
    const marineY = canvasHeight - 50;
    ctx.font = '30px "Pirata One"'; // Could use a different font if desired
    ctx.fillStyle = textSecondaryColor;
    ctx.fillText(marineText.toUpperCase(), canvasWidth / 2, marineY);

    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 One Piece Wanted Poster Creator is an online tool that allows users to create custom wanted posters featuring their favorite characters from the One Piece universe. Users can upload an image and add personalized text for the character’s name, bounty, and titles like ‘WANTED’ and ‘DEAD OR ALIVE’. This tool is perfect for fans who want to design unique, themed decorations, party invitations, or social media posts inspired by the popular anime and manga series. With a user-friendly interface, the poster can be customized to include distinct fonts and a styled background that resembles traditional parchment.

Leave a Reply

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