Skip to content
Digital solutions for a better tomorrow🇮🇳 India  ·  EN  ·  Client Login
GLIRABHARAT
Home / Blog / Build a Bulk Image Generator with HTML

Glira Resources

Build a Bulk Image Generator with HTML

September 5, 2026

The following example is a working browser-based bulk image generator.

It doesn’t just display HTML cards. It uses the HTML Canvas API to create actual image files that can be downloaded as PNG images.

You can enter multiple titles, select an image ratio, choose a font, adjust the font size, select a design style, and generate multiple images.


Complete HTML Code

Create a file called:

bulk-image-generator.html

Then paste the complete code below into it and open the file in your browser.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">

<title>Bulk Image Generator</title>

<style>

* {
    box-sizing: border-box;
}

body {
    margin: 0;
    font-family: Arial, sans-serif;
    background: #f3f4f6;
    color: #111827;
}

.container {
    max-width: 1200px;
    margin: auto;
    padding: 30px 20px;
}

h1 {
    margin-bottom: 8px;
}

.subtitle {
    color: #6b7280;
    margin-bottom: 25px;
}

.panel {
    background: #ffffff;
    padding: 22px;
    border-radius: 14px;
    margin-bottom: 25px;
    box-shadow: 0 5px 20px rgba(0,0,0,0.06);
}

textarea {
    width: 100%;
    min-height: 160px;
    padding: 15px;
    border: 1px solid #d1d5db;
    border-radius: 10px;
    resize: vertical;
    font-size: 16px;
}

.controls {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
    gap: 15px;
    margin-top: 20px;
}

.control label {
    display: block;
    font-size: 14px;
    font-weight: 600;
    margin-bottom: 7px;
}

select,
input[type="number"],
input[type="color"] {
    width: 100%;
    height: 42px;
    border: 1px solid #d1d5db;
    border-radius: 8px;
    padding: 8px;
    background: white;
}

input[type="range"] {
    width: 100%;
}

button {
    border: none;
    padding: 12px 18px;
    border-radius: 8px;
    cursor: pointer;
    font-weight: 600;
    margin-top: 18px;
    margin-right: 8px;
}

.generate {
    background: #111827;
    color: white;
}

.download-all {
    background: #2563eb;
    color: white;
}

.preview-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
    gap: 20px;
}

.image-item {
    background: white;
    padding: 12px;
    border-radius: 12px;
    box-shadow: 0 5px 18px rgba(0,0,0,0.07);
}

.image-item img {
    width: 100%;
    display: block;
    border-radius: 8px;
}

.image-title {
    font-size: 14px;
    margin-top: 10px;
    font-weight: 600;
}

.download-one {
    width: 100%;
    margin-top: 10px;
    background: #e5e7eb;
    color: #111827;
}

.status {
    margin-top: 15px;
    color: #6b7280;
}

</style>
</head>

<body>

<div class="container">

    <h1>Bulk Image Generator</h1>

    <p class="subtitle">
        Create multiple images from a list of titles directly in your browser.
    </p>

    <div class="panel">

        <h2>1. Enter Your Text</h2>

        <p>
            Enter one title or phrase per line.
        </p>

        <textarea id="textInput"
        placeholder="Example:

10 Writing Tips
How to Start a Blog
SEO Basics
Content Marketing
Social Media Tips"></textarea>

        <div class="controls">

            <div class="control">
                <label>Image Ratio</label>

                <select id="ratio">
                    <option value="landscape">16:9 Landscape</option>
                    <option value="square">1:1 Square</option>
                    <option value="portrait">4:5 Portrait</option>
                    <option value="story">9:16 Story</option>
                </select>
            </div>

            <div class="control">
                <label>Font</label>

                <select id="font">
                    <option value="Arial">Arial</option>
                    <option value="Georgia">Georgia</option>
                    <option value="Verdana">Verdana</option>
                    <option value="Trebuchet MS">Trebuchet MS</option>
                    <option value="Courier New">Courier New</option>
                </select>
            </div>

            <div class="control">
                <label>Font Size</label>

                <input
                    type="number"
                    id="fontSize"
                    value="52"
                    min="20"
                    max="120">
            </div>

            <div class="control">
                <label>Text Alignment</label>

                <select id="alignment">
                    <option value="center">Center</option>
                    <option value="left">Left</option>
                    <option value="right">Right</option>
                </select>
            </div>

            <div class="control">
                <label>Design Style</label>

                <select id="style">
                    <option value="modern">Modern</option>
                    <option value="minimal">Minimal</option>
                    <option value="dark">Dark</option>
                    <option value="gradient">Gradient</option>
                    <option value="bold">Bold</option>
                </select>
            </div>

            <div class="control">
                <label>Custom Background</label>

                <input
                    type="color"
                    id="background"
                    value="#2563eb">
            </div>

        </div>

        <button class="generate" onclick="generateImages()">
            Generate Images
        </button>

        <button class="download-all" onclick="downloadAll()">
            Download All
        </button>

        <div id="status" class="status"></div>

    </div>

    <div class="panel">

        <h2>Generated Images</h2>

        <div id="preview" class="preview-grid"></div>

    </div>

</div>


<script>

let generatedImages = [];


/* -------------------------
   IMAGE SIZE
------------------------- */

function getImageSize() {

    const ratio = document.getElementById("ratio").value;

    if (ratio === "square") {
        return {
            width: 1080,
            height: 1080
        };
    }

    if (ratio === "portrait") {
        return {
            width: 1080,
            height: 1350
        };
    }

    if (ratio === "story") {
        return {
            width: 1080,
            height: 1920
        };
    }

    return {
        width: 1200,
        height: 675
    };
}


/* -------------------------
   TEXT WRAPPING
------------------------- */

function wrapText(ctx, text, maxWidth) {

    const words = text.split(" ");
    const lines = [];

    let line = "";

    words.forEach(word => {

        const testLine = line
            ? line + " " + word
            : word;

        const width = ctx.measureText(testLine).width;

        if (width > maxWidth && line) {

            lines.push(line);
            line = word;

        } else {

            line = testLine;

        }

    });

    if (line) {
        lines.push(line);
    }

    return lines;
}


/* -------------------------
   BACKGROUND
------------------------- */

function drawBackground(ctx, width, height, style, customColor) {

    if (style === "modern") {

        ctx.fillStyle = customColor;
        ctx.fillRect(0, 0, width, height);

        ctx.fillStyle = "rgba(255,255,255,0.12)";
        ctx.beginPath();
        ctx.arc(
            width * 0.85,
            height * 0.2,
            height * 0.25,
            0,
            Math.PI * 2
        );
        ctx.fill();

    }

    else if (style === "minimal") {

        ctx.fillStyle = "#ffffff";
        ctx.fillRect(0, 0, width, height);

        ctx.fillStyle = customColor;
        ctx.fillRect(0, 0, 18, height);

    }

    else if (style === "dark") {

        ctx.fillStyle = "#111111";
        ctx.fillRect(0, 0, width, height);

        ctx.fillStyle = customColor;
        ctx.fillRect(
            0,
            height - 18,
            width,
            18
        );

    }

    else if (style === "gradient") {

        const gradient = ctx.createLinearGradient(
            0,
            0,
            width,
            height
        );

        gradient.addColorStop(0, customColor);
        gradient.addColorStop(1, "#111827");

        ctx.fillStyle = gradient;
        ctx.fillRect(0, 0, width, height);

    }

    else if (style === "bold") {

        ctx.fillStyle = "#000000";
        ctx.fillRect(0, 0, width, height);

        ctx.fillStyle = customColor;

        ctx.fillRect(
            40,
            40,
            width - 80,
            height - 80
        );

    }

}


/* -------------------------
   GENERATE SINGLE IMAGE
------------------------- */

function createImage(text) {

    const size = getImageSize();

    const canvas = document.createElement("canvas");

    canvas.width = size.width;
    canvas.height = size.height;

    const ctx = canvas.getContext("2d");

    const style =
        document.getElementById("style").value;

    const font =
        document.getElementById("font").value;

    const fontSize =
        parseInt(
            document.getElementById("fontSize").value
        );

    const alignment =
        document.getElementById("alignment").value;

    const customColor =
        document.getElementById("background").value;


    /* Background */

    drawBackground(
        ctx,
        size.width,
        size.height,
        style,
        customColor
    );


    /* Text color */

    if (style === "minimal") {

        ctx.fillStyle = "#111111";

    } else if (style === "bold") {

        ctx.fillStyle = "#ffffff";

    } else {

        ctx.fillStyle = "#ffffff";

    }


    /* Font */

    let weight = "700";

    if (style === "minimal") {
        weight = "600";
    }

    ctx.font =
        weight +
        " " +
        fontSize +
        "px " +
        font;


    ctx.textAlign = alignment;

    ctx.textBaseline = "middle";


    /* Text position */

    let x = size.width / 2;

    if (alignment === "left") {
        x = 90;
    }

    if (alignment === "right") {
        x = size.width - 90;
    }


    /* Wrap text */

    const maxWidth =
        size.width - 180;

    const lines =
        wrapText(
            ctx,
            text,
            maxWidth
        );


    const lineHeight =
        fontSize * 1.25;

    const totalHeight =
        lines.length * lineHeight;

    let y =
        (size.height - totalHeight) / 2;


    /* Draw lines */

    lines.forEach(line => {

        ctx.fillText(
            line,
            x,
            y + lineHeight / 2
        );

        y += lineHeight;

    });


    return canvas.toDataURL(
        "image/png"
    );
}


/* -------------------------
   GENERATE ALL IMAGES
------------------------- */

function generateImages() {

    const input =
        document.getElementById("textInput").value;

    const items =
        input
        .split("\n")
        .map(item => item.trim())
        .filter(item => item !== "");


    const preview =
        document.getElementById("preview");

    preview.innerHTML = "";

    generatedImages = [];


    if (items.length === 0) {

        document.getElementById("status").textContent =
            "Please enter at least one title.";

        return;
    }


    items.forEach((text, index) => {

        const image =
            createImage(text);

        generatedImages.push({
            name: text,
            data: image
        });


        const item =
            document.createElement("div");

        item.className =
            "image-item";


        item.innerHTML = `
            <img src="${image}" alt="${escapeHtml(text)}">

            <div class="image-title">
                ${escapeHtml(text)}
            </div>

            <button
                class="download-one"
                onclick="downloadImage(${index})">
                Download PNG
            </button>
        `;


        preview.appendChild(item);

    });


    document.getElementById("status").textContent =
        items.length +
        " image(s) generated successfully.";

}


/* -------------------------
   DOWNLOAD ONE IMAGE
------------------------- */

function downloadImage(index) {

    const image =
        generatedImages[index];

    const link =
        document.createElement("a");

    link.download =
        createFileName(image.name) +
        ".png";

    link.href =
        image.data;

    link.click();

}


/* -------------------------
   DOWNLOAD ALL
------------------------- */

function downloadAll() {

    if (generatedImages.length === 0) {

        alert(
            "Generate some images first."
        );

        return;
    }


    generatedImages.forEach(
        (image, index) => {

            setTimeout(() => {

                downloadImage(index);

            }, index * 400);

        }
    );

}


/* -------------------------
   FILE NAME
------------------------- */

function createFileName(text) {

    return text
        .toLowerCase()
        .replace(/[^a-z0-9]+/g, "-")
        .replace(/^-|-$/g, "")
        .substring(0, 60);

}


/* -------------------------
   HTML ESCAPE
------------------------- */

function escapeHtml(text) {

    return text
        .replace(/&/g, "&amp;")
        .replace(/</g, "&lt;")
        .replace(/>/g, "&gt;")
        .replace(/"/g, "&quot;")
        .replace(/'/g, "&#039;");

}

</script>

</body>
</html>

What This Example Can Do

This small application already provides several useful controls.

Font Controls

Users can select:

  • Arial
  • Georgia
  • Verdana
  • Trebuchet MS
  • Courier New

They can also change the font size.

For example:

20px → 120px


Image Ratio Controls

The tool supports four common formats:

RatioSizeUseful For
16:91200 × 675Blog / website
1:11080 × 1080Square posts
4:51080 × 1350Portrait posts
9:161080 × 1920Stories / vertical content

This makes the same generator useful for different types of content.


Five Simple Design Styles

The example includes five basic styles.

1. Modern

A clean colored background with a subtle decorative circle.

2. Minimal

A white background with a simple colored accent.

3. Dark

A dark background with a colored bottom accent.

4. Gradient

A gradient background combining the selected color with a dark shade.

5. Bold

A strong high-contrast design with a large colored panel.

These styles can later be expanded into much more sophisticated templates.


How the Bulk Generation Works

The user enters:

10 Writing Tips
How to Start a Blog
SEO Basics
Content Marketing
Social Media Tips

The JavaScript splits the text at each new line.

It then creates an image for every line.

The result is:

Image 1 → 10 Writing Tips
Image 2 → How to Start a Blog
Image 3 → SEO Basics
Image 4 → Content Marketing
Image 5 → Social Media Tips

Each image is generated using the Canvas API and converted into a PNG data URL.

That means the browser is creating an actual image file, rather than simply displaying an HTML preview.


How You Can Expand the Tool

This basic version can become a much more powerful application.

You could add:

  • Custom logo upload
  • Custom background image
  • Multiple text fields
  • Subtitle support
  • Brand colors
  • Custom fonts
  • Font weight controls
  • Text spacing
  • Image filters
  • Templates
  • CSV upload
  • Excel upload
  • ZIP download
  • Drag-and-drop design editor
  • AI-generated images
  • AI-generated text
  • Database storage
  • User accounts

For example, a CSV could contain hundreds of titles and the tool could automatically generate hundreds of images.


From HTML Tool to Real Web Application

A simple HTML tool is a good starting point.

But if you want users to access the tool from your website, you can turn it into a proper web application.

For example:

User → Upload CSV → Select Template → Select Font → Select Ratio → Generate → Download ZIP

This is where a simple browser experiment can become a useful online product.


Want to Build Your Own Tool?

If you have an idea for a bulk image generator or another custom online tool, you don’t necessarily need to start with a large application.

Start with the basic workflow, test whether people find it useful, and then add advanced features.

Want to build your own custom web tool?

Contact Glira at:

9150999566

We can help turn your idea into a practical web-based tool.

Try Now

Bulk Image Generator

Bulk Image Generator

Create multiple images from a list of titles directly in your browser.

1. Enter Your Text

Enter one title or phrase per line.

Generated Images