Please bookmark this page to avoid losing your image tool!

Image Underground Resistance Flyer 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,
    threshold = 128,
    invertBackground = 0, // 0 for normal, 1 for inverted background
    textLine1 = "UNDERGROUND",
    textLine2 = "RESISTANCE",
    fontFamilyToUse = "Staatliches", // Specific font to attempt loading, e.g., "Staatliches". Falls back to Impact/Charcoal.
    fontSizeRatio = 0.1, // Font size relative to canvas width
    textColor = "#FFFFFF",
    barColor = "#000000",
    barPosition = "center", // "top", "center", "bottom"
    barPaddingVerticalRatio = 0.2, // Padding above/below text within bar, relative to total text height
    interlineSpacingRatio = 0.1 // Space between text lines, relative to text height of first line
) {

    const STAATLICHES_FONT_SLUG = "staatliches"; // Lowercase identifier for the font
    const STAATLICHES_FONT_FACE_NAME = 'UR_Flyer_Staatliches'; // Unique FontFace name
    const STAATLICHES_FONT_URL = 'https://fonts.gstatic.com/s/staatliches/v10/HI_OiY8KO6hCsQSoAPmtMYeb.woff2';
    
    let finalFontStack = fontFamilyToUse; // Default to user-specified font family

    if (fontFamilyToUse.toLowerCase() === STAATLICHES_FONT_SLUG) {
        // If user requests "Staatliches" (or it's the default), try to load it
        finalFontStack = "Impact, Charcoal, sans-serif"; // Fallback if Staatliches fails

        if (document.fonts) {
            let isStaatlichesReady = false;
            // Check if font is already loaded by this unique name
            for (const font of document.fonts.values()) {
                if (font.family === STAATLICHES_FONT_FACE_NAME) {
                    isStaatlichesReady = true;
                    break;
                }
            }

            if (isStaatlichesReady) {
                finalFontStack = `${STAATLICHES_FONT_FACE_NAME}, ${finalFontStack}`;
            } else {
                try {
                    const fontFace = new FontFace(STAATLICHES_FONT_FACE_NAME, `url(${STAATLICHES_FONT_URL})`);
                    await fontFace.load();
                    document.fonts.add(fontFace);
                    // console.log(`${STAATLICHES_FONT_FACE_NAME} font loaded.`);
                    finalFontStack = `${STAATLICHES_FONT_FACE_NAME}, ${finalFontStack}`;
                } catch (e) {
                    console.error(`Font ${STAATLICHES_FONT_FACE_NAME} from ${STAATLICHES_FONT_URL} failed to load:`, e);
                    // Fallback (already set to Impact...) will be used
                }
            }
        } else {
            console.warn("document.fonts API not available. Cannot dynamically load Staatliches. Using fallback fonts.");
        }
    }
    // else, finalFontStack remains the user-provided fontFamilyToUse

    const canvas = document.createElement('canvas');
    const ctx = canvas.getContext('2d');
    
    canvas.width = originalImg.naturalWidth || originalImg.width || 300;
    canvas.height = originalImg.naturalHeight || originalImg.height || 150;

    // Draw and Process Background Image
    ctx.drawImage(originalImg, 0, 0, canvas.width, canvas.height);
    const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
    const data = imageData.data;

    for (let i = 0; i < data.length; i += 4) {
        const r = data[i];
        const g = data[i + 1];
        const b = data[i + 2];
        const gray = 0.299 * r + 0.587 * g + 0.114 * b;
        
        let outputColor = gray > threshold ? 255 : 0;

        if (parseInt(invertBackground) === 1) {
            outputColor = 255 - outputColor;
        }
        
        data[i] = outputColor;
        data[i + 1] = outputColor;
        data[i + 2] = outputColor;
        // data[i+3] (alpha) remains unchanged
    }
    ctx.putImageData(imageData, 0, 0);

    // Text Rendering
    if (textLine1 || textLine2) {
        const baseFontSize = Math.max(10, Math.floor(canvas.width * fontSizeRatio));
        ctx.font = `${baseFontSize}px ${finalFontStack}`;
        ctx.textAlign = "center";
        ctx.textBaseline = "middle";

        let textVisualHeight1 = 0;
        if (textLine1) {
            const metrics = ctx.measureText(textLine1.toUpperCase());
            const ascent = metrics.actualBoundingBoxAscent !== undefined ? metrics.actualBoundingBoxAscent : baseFontSize * 0.75;
            const descent = metrics.actualBoundingBoxDescent !== undefined ? metrics.actualBoundingBoxDescent : baseFontSize * 0.25;
            textVisualHeight1 = ascent + descent;
            if (textVisualHeight1 <= 0 && baseFontSize > 0) textVisualHeight1 = baseFontSize; // Fallback
        }

        let textVisualHeight2 = 0;
        if (textLine2) {
            const metrics = ctx.measureText(textLine2.toUpperCase());
            const ascent = metrics.actualBoundingBoxAscent !== undefined ? metrics.actualBoundingBoxAscent : baseFontSize * 0.75;
            const descent = metrics.actualBoundingBoxDescent !== undefined ? metrics.actualBoundingBoxDescent : baseFontSize * 0.25;
            textVisualHeight2 = ascent + descent;
            if (textVisualHeight2 <= 0 && baseFontSize > 0) textVisualHeight2 = baseFontSize; // Fallback
        }
        
        const hasLine1 = (textLine1 && textVisualHeight1 > 0);
        const hasLine2 = (textLine2 && textVisualHeight2 > 0);
        
        const interlineActualSpace = (hasLine1 && hasLine2) ? (textVisualHeight1 * interlineSpacingRatio) : 0;
        
        let totalTextContentHeight = 0;
        if (hasLine1) totalTextContentHeight += textVisualHeight1;
        if (hasLine2) totalTextContentHeight += textVisualHeight2;
        if (hasLine1 && hasLine2) totalTextContentHeight += interlineActualSpace;

        if (totalTextContentHeight === 0 && (textLine1 || textLine2)) {
             let lineCountFallback = 0;
             if (textLine1) lineCountFallback++; if (textLine2) lineCountFallback++;
             if (lineCountFallback > 0) {
                totalTextContentHeight = baseFontSize * lineCountFallback;
                if (lineCountFallback > 1) totalTextContentHeight += baseFontSize * interlineSpacingRatio;
             }
        }
        
        const barPaddingPx = Math.max(5, totalTextContentHeight * barPaddingVerticalRatio);
        const barHeight = totalTextContentHeight + 2 * barPaddingPx;

        let barY;
        if (barPosition === "top") {
            barY = 0;
        } else if (barPosition === "bottom") {
            barY = canvas.height - barHeight;
        } else { // Default: center
            barY = (canvas.height - barHeight) / 2;
        }
        
        barY = Math.max(0, barY);
        const actualBarHeight = Math.min(barHeight, canvas.height - barY);

        if (actualBarHeight > 0 && totalTextContentHeight > 0) {
            ctx.fillStyle = barColor;
            ctx.fillRect(0, barY, canvas.width, actualBarHeight);

            ctx.fillStyle = textColor;
            let currentTextYAnchor = barY + barPaddingPx; // This is the top of the first line's content area

            if (hasLine1) {
                const y1 = currentTextYAnchor + textVisualHeight1 / 2;
                ctx.fillText(textLine1.toUpperCase(), canvas.width / 2, y1);
                currentTextYAnchor += textVisualHeight1;
                if (hasLine2) {
                     currentTextYAnchor += interlineActualSpace;
                }
            }
            
            if (hasLine2) {
                const y2 = currentTextYAnchor + textVisualHeight2 / 2;
                ctx.fillText(textLine2.toUpperCase(), canvas.width / 2, y2);
            }
        }
    }
    
    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 Underground Resistance Flyer Creator is a web-based tool designed to transform images into stylized flyers suitable for promoting underground themes and resistance messages. Users can upload an image, apply a threshold for converting the image to black and white, and customize it with text lines, font styles, colors, and positioning. This tool is ideal for activists, artists, or anyone looking to create striking promotional material for events, gatherings, or causes, allowing for both creative expression and effective communication of their message.

Leave a Reply

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

Other Image Tools:

Image Retro Video Game Box Art Creator

Image Captain’s Naval Journal Creator

Image Renaissance Painting Frame Creator

Image Lost Civilization Artifact Creator

Image Da Vinci Notebook Page Creator

Image Dystopian Citizen ID Creator

Image Monster Hunter Bestiary Creator

Image Vintage Carnival Sideshow Poster Creator

Image Space Explorer’s Log Creator

Image Neolithic Petroglyph Frame Creator

Image Ukiyo-e Japanese Woodblock Print Creator

Image Persian Miniature Painting Creator

Image Sci-Fi Movie Poster Template Creator

Image Horror Movie Poster Template

Image Social Media Milestone Certificate Creator

Halloween Death Certificate Template

Image Anatomical Illustration Frame Creator

Image Romance Novel Cover Template Creator

Image Tabloid Headline Template

Image Space Mission Patch Template Creator

Image Cassette Tape Cover Template Creator

Image Passport Page Template Generator

Image Old Map Frame With Compass Rose Decorator

Image Diploma and Degree Certificate Framer

Image Soviet Propaganda Poster Style Generator

Image Yu-Gi-Oh Card Template Creator

Image Ancient Roman Greek Tablet Frame Creator

Image Marriage Certificate Template Creator

Image Video Game Achievement Frame Creator

Image Newspaper Front Page Template Creator

Image Botanical Illustration Frame Creator

Image Vinyl Record Sleeve Template Creator

Vintage Photo Booth Strip Template Generator

Image Cyberpunk Interface Frame Designer

Image Detective Novel Cover Template

Image Achievement Certificate Framer

See All →