Please bookmark this page to avoid losing your image tool!

New York ID Mockup Generator

(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,
    firstName = "JOHN",
    lastName = "DOE",
    dob = "01/01/1990",
    address1 = "123 MAIN ST",
    address2 = "ALBANY NY 12201",
    idNumber = "123 456 789",
    sex = "M",
    height = "5-08",
    eyes = "BRO",
    issueDate = "01/01/2023",
    expDate = "01/01/2031",
    documentClass = "D"
) {
    // 1. Prepare Font
    const fontName = 'Caveat';
    try {
        const fontUrl = `https://fonts.googleapis.com/css2?family=${fontName}:wght@700&display=swap`;
        const style = document.createElement('style');
        style.textContent = `@import url('${fontUrl}');`;
        document.head.appendChild(style);
        await document.fonts.ready;
        try {
            await document.fonts.load(`700 48px ${fontName}`);
        } catch (e) {}
    } catch (err) {
        console.warn("Could not load Caveat font, will use cursive fallback.");
    }

    // 2. Setup Canvas
    const canvas = document.createElement("canvas");
    const width = 1010;
    const heightPix = 636;
    canvas.width = width;
    canvas.height = heightPix;
    const ctx = canvas.getContext("2d");

    // 3. Draw Background Gradient
    const bgGradient = ctx.createLinearGradient(0, 0, width, heightPix);
    bgGradient.addColorStop(0, "#cbe3fc");    // Light blue top
    bgGradient.addColorStop(0.3, "#f4f8fb");  // Fading mostly white
    bgGradient.addColorStop(0.7, "#fcf7eb");  // Soft yellow
    bgGradient.addColorStop(1, "#f1e5ba");    // Deeper yellow base
    ctx.fillStyle = bgGradient;
    ctx.fillRect(0, 0, width, heightPix);

    // 4. Background Guilloche/Security Lines
    ctx.strokeStyle = "rgba(100, 140, 200, 0.15)";
    ctx.lineWidth = 1;
    for (let i = -50; i < heightPix + 50; i += 25) {
        ctx.beginPath();
        ctx.moveTo(0, i);
        for (let x = 0; x <= width; x += 60) {
            ctx.quadraticCurveTo(x + 30, i + 30, x + 60, i);
        }
        ctx.stroke();
    }

    // Abstract mountain/state silhouette in middle background
    ctx.fillStyle = "rgba(10, 60, 120, 0.04)";
    ctx.beginPath();
    ctx.moveTo(0, 250);
    ctx.lineTo(250, 150);
    ctx.lineTo(500, 260);
    ctx.lineTo(800, 160);
    ctx.lineTo(1010, 300);
    ctx.lineTo(1010, heightPix);
    ctx.lineTo(0, heightPix);
    ctx.closePath();
    ctx.fill();

    // 5. Draw Header
    ctx.fillStyle = "#0A2458"; 
    ctx.font = "bold 52px Georgia, serif";
    ctx.fillText("NEW YORK STATE", 40, 70);

    ctx.fillStyle = "#7A8A9E";
    ctx.font = "bold 22px Arial, sans-serif";
    ctx.fillText("DRIVER LICENSE", 42, 105);

    // Real ID star top right
    function drawStar(cx, cy, spikes, outerRadius, innerRadius) {
        let rot = (Math.PI / 2) * 3;
        let x = cx;
        let y = cy;
        let step = Math.PI / spikes;

        ctx.beginPath();
        ctx.moveTo(cx, cy - outerRadius);
        for (let i = 0; i < spikes; i++) {
            x = cx + Math.cos(rot) * outerRadius;
            y = cy + Math.sin(rot) * outerRadius;
            ctx.lineTo(x, y);
            rot += step;
            x = cx + Math.cos(rot) * innerRadius;
            y = cy + Math.sin(rot) * innerRadius;
            ctx.lineTo(x, y);
            rot += step;
        }
        ctx.closePath();
        ctx.fill();
    }

    ctx.fillStyle = "black";
    ctx.beginPath();
    ctx.arc(930, 70, 28, 0, Math.PI * 2);
    ctx.fill();
    ctx.fillStyle = "gold";
    drawStar(930, 70, 5, 26, 11);

    // 6. Draw Photos
    function createRoundRectPath(context, x, y, w, h, radius) {
        context.beginPath();
        context.moveTo(x + radius, y);
        context.arcTo(x + w, y, x + w, y + h, radius);
        context.arcTo(x + w, y + h, x, y + h, radius);
        context.arcTo(x, y + h, x, y, radius);
        context.arcTo(x, y, x + w, y, radius);
        context.closePath();
    }

    function drawCroppedImage(img, dx, dy, dw, dh, alpha = 1.0) {
        ctx.save();
        ctx.globalAlpha = alpha;
        const imgRatio = img.width / img.height;
        const targetRatio = dw / dh;
        let sx, sy, sw, sh;
        if (imgRatio > targetRatio) {
            sh = img.height;
            sw = sh * targetRatio;
            sx = (img.width - sw) / 2;
            sy = 0;
        } else {
            sw = img.width;
            sh = sw / targetRatio;
            sx = 0;
            sy = (img.height - sh) / 2;
        }
        createRoundRectPath(ctx, dx, dy, dw, dh, 15);
        ctx.clip();
        ctx.drawImage(img, sx, sy, sw, sh, dx, dy, dw, dh);
        
        // Inner stroke
        ctx.lineWidth = 1;
        ctx.strokeStyle = "rgba(0,0,0,0.2)";
        ctx.stroke();
        ctx.restore();
    }

    // Main portrait
    drawCroppedImage(originalImg, 40, 140, 260, 340);
    // Ghost image (Bottom right)
    drawCroppedImage(originalImg, 810, 370, 140, 185, 0.35);

    // Simulated partial seal overlap on photo
    ctx.save();
    ctx.globalAlpha = 0.4;
    ctx.beginPath();
    ctx.arc(300, 430, 45, 0, Math.PI * 2);
    ctx.strokeStyle = "#e8b923";
    ctx.lineWidth = 3;
    ctx.stroke();
    // Seal inner text
    ctx.translate(300, 430);
    ctx.rotate(-Math.PI / 4);
    ctx.font = "bold 14px Arial";
    ctx.fillStyle = "#e8b923";
    ctx.textAlign = "center";
    ctx.fillText("SEAL OF NY", 0, 5);
    ctx.restore();

    // 7. Draw ID Data Fields
    function drawField(num, label, value, x, y, valColor = "#111") {
        ctx.fillStyle = "#C3212D"; 
        ctx.font = "bold 13px Arial";
        ctx.textAlign = "right";
        ctx.fillText(num, x + 18, y);

        ctx.fillStyle = "#555";
        ctx.font = "bold 10px Arial";
        ctx.textAlign = "left";
        ctx.fillText(label, x + 25, y);

        ctx.fillStyle = valColor;
        ctx.font = "bold 23px Arial";
        ctx.fillText(value, x + 25, y + 24);
    }

    let curY = 160;
    let col1 = 330;
    let col2 = 640;
    let col3 = 820;

    drawField("4d", "ID NUMBER", idNumber, col1, curY);
    drawField("9", "CLASS", documentClass, col2, curY);
    curY += 50;

    drawField("3", "DOB", dob, col1, curY, "#C3212D"); // DOB in Red
    drawField("4a", "ISSUED", issueDate, col2, curY);
    drawField("4b", "EXPIRES", expDate, col3, curY, "#C3212D"); // Exp in Red
    curY += 50;

    drawField("1", "LAST NAME", lastName, col1, curY);
    curY += 50;

    drawField("2", "FIRST NAME", firstName, col1, curY);
    curY += 50;

    drawField("8", "ADDRESS", address1, col1, curY);
    ctx.fillStyle = "#111"; 
    ctx.font = "bold 23px Arial";
    ctx.fillText(address2, col1 + 25, curY + 48);
    curY += 85;

    // Mini Table for Characteristics (Sex, Ht, Eyes)
    const chY = curY;
    // SEX
    ctx.fillStyle = "#C3212D"; ctx.font = "bold 11px Arial"; ctx.fillText("15", col1+18, chY);
    ctx.fillStyle = "#555"; ctx.font = "bold 9px Arial"; ctx.fillText("SEX", col1+25, chY);
    ctx.fillStyle = "#111"; ctx.font = "bold 18px Arial"; ctx.fillText(sex, col1+25, chY+20);

    // HT
    ctx.fillStyle = "#C3212D"; ctx.font = "bold 11px Arial"; ctx.fillText("16", col1+98, chY);
    ctx.fillStyle = "#555"; ctx.font = "bold 9px Arial"; ctx.fillText("HT", col1+105, chY);
    ctx.fillStyle = "#111"; ctx.font = "bold 18px Arial"; ctx.fillText(height, col1+105, chY+20);

    // EYES
    ctx.fillStyle = "#C3212D"; ctx.font = "bold 11px Arial"; ctx.fillText("18", col1+178, chY);
    ctx.fillStyle = "#555"; ctx.font = "bold 9px Arial"; ctx.fillText("EYES", col1+185, chY);
    ctx.fillStyle = "#111"; ctx.font = "bold 18px Arial"; ctx.fillText(eyes, col1+185, chY+20);

    // 8. Signature
    ctx.fillStyle = "rgba(0, 0, 0, 0.85)";
    ctx.font = `700 48px '${fontName}', cursive, serif`;
    ctx.textAlign = "left";
    // Place under the main photo roughly centered
    ctx.fillText(firstName + " " + lastName, 60, 550);

    // 9. Watermark (MOCK UP strictly in corners to maintain transparency and legal constraint)
    function drawWatermark(x, y, rotation) {
        ctx.save();
        ctx.translate(x, y);
        ctx.rotate(rotation);
        ctx.font = "bold 64px Arial, sans-serif";
        ctx.fillStyle = "rgba(220, 20, 20, 0.7)";
        ctx.strokeStyle = "rgba(255, 255, 255, 0.8)";
        ctx.lineWidth = 4;
        ctx.textAlign = "center";
        ctx.textBaseline = "middle";
        ctx.strokeText("MOCK UP", 0, 0);
        ctx.fillText("MOCK UP", 0, 0);
        ctx.restore();
    }

    // Top Right Corner Mockup
    drawWatermark(width - 160, 140, -Math.PI / 6);
    // Bottom Left Corner Mockup
    drawWatermark(180, heightPix - 60, -Math.PI / 6);

    // Frame Border
    ctx.lineWidth = 3;
    ctx.strokeStyle = "#ccc";
    createRoundRectPath(ctx, 1, 1, width - 2, heightPix - 2, 8);
    ctx.stroke();

    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 New York ID Mockup Generator is a tool designed to create realistic visual mockups of a New York State driver’s license. Users can upload a portrait photo and customize various identity details, including name, date of birth, address, ID number, gender, height, eye color, and expiration dates. The tool automatically overlays this information onto a template featuring security-style gradients, background patterns, and a signature field. This utility is useful for graphic designers, filmmakers, or creative professionals who need to generate placeholder identification documents for digital assets, theatrical props, or visual storytelling projects.

Leave a Reply

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