Please bookmark this page to avoid losing your image tool!

New York ID Image 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,
    name = "DOE, JANE",
    idNumber = "123 456 789",
    dob = "01/01/1990",
    address1 = "123 EMPIRE BLVD",
    address2 = "NEW YORK, NY 10001",
    sex = "F",
    heightVal = "5'-06\"",
    eyes = "BRN",
    issueDate = "08/15/2022",
    expDate = "01/01/2030",
    documentClass = "D"
) {
    // Inject signature font
    if (!document.getElementById("caveat-font-id-gen")) {
        const style = document.createElement("style");
        style.id = "caveat-font-id-gen";
        style.innerHTML = `@import url('https://fonts.googleapis.com/css2?family=Caveat:wght@700&display=swap');`;
        document.head.appendChild(style);
    }
    
    // Wait for the font to load
    await document.fonts.ready;
    try {
        await document.fonts.load('40px "Caveat"');
    } catch (e) {
        console.warn("Font loading issue, falling back to cursive.");
    }

    // Set up canvas
    const canvas = document.createElement("canvas");
    const canvasWidth = 860;
    const canvasHeight = 540;
    canvas.width = canvasWidth;
    canvas.height = canvasHeight;
    const ctx = canvas.getContext("2d");

    // Enable smooth rendering
    ctx.imageSmoothingEnabled = true;
    ctx.imageSmoothingQuality = 'high';

    // 1. Draw Background
    // Base card color and border radius clipping
    ctx.beginPath();
    ctx.moveTo(15, 0);
    ctx.lineTo(canvasWidth - 15, 0);
    ctx.quadraticCurveTo(canvasWidth, 0, canvasWidth, 15);
    ctx.lineTo(canvasWidth, canvasHeight - 15);
    ctx.quadraticCurveTo(canvasWidth, canvasHeight, canvasWidth - 15, canvasHeight);
    ctx.lineTo(15, canvasHeight);
    ctx.quadraticCurveTo(0, canvasHeight, 0, canvasHeight - 15);
    ctx.lineTo(0, 15);
    ctx.quadraticCurveTo(0, 0, 15, 0);
    ctx.clip();

    // Gradient background to emulate the complex NY backdrop
    const bgGradient = ctx.createLinearGradient(0, 0, canvasWidth, canvasHeight);
    bgGradient.addColorStop(0, "#cbe3f5"); // Light blue
    bgGradient.addColorStop(0.5, "#ffffff"); // White
    bgGradient.addColorStop(1, "#f2eed3"); // Light yellow
    ctx.fillStyle = bgGradient;
    ctx.fillRect(0, 0, canvasWidth, canvasHeight);

    // Guilloche / Wave Patterns
    ctx.save();
    ctx.strokeStyle = "rgba(0, 70, 150, 0.15)";
    ctx.lineWidth = 1;
    for (let y = 100; y < canvasHeight; y += 15) {
        ctx.beginPath();
        for (let x = 0; x <= canvasWidth; x += 30) {
            ctx.quadraticCurveTo(x + 15, y + 10, x + 30, y);
        }
        ctx.stroke();
    }
    // Vertical subtle lines
    ctx.strokeStyle = "rgba(0, 70, 150, 0.05)";
    for (let x = 0; x < canvasWidth; x += 8) {
        ctx.beginPath();
        ctx.moveTo(x, 90);
        ctx.lineTo(x + 20, canvasHeight);
        ctx.stroke();
    }
    ctx.restore();

    // Fake State Seal / Watermark Center Graphic
    ctx.save();
    ctx.globalAlpha = 0.2;
    ctx.beginPath();
    ctx.arc(460, 310, 140, 0, Math.PI * 2);
    ctx.lineWidth = 4;
    ctx.strokeStyle = "#e8b010";
    ctx.stroke();
    ctx.fillStyle = "#e8b010";
    ctx.textAlign = "center";
    ctx.textBaseline = "middle";
    ctx.font = "bold 32px Arial";
    ctx.fillText("EXCELSIOR", 460, 310);
    ctx.beginPath();
    ctx.arc(460, 310, 130, 0, Math.PI * 2);
    ctx.lineWidth = 2;
    ctx.stroke();
    ctx.restore();

    // 2. Draw Top Headers
    ctx.fillStyle = "#0c2340"; // Dark navy blue
    ctx.fillRect(0, 0, canvasWidth, 80);
    // Yellow stripe underneath header
    ctx.fillStyle = "#fdb813"; 
    ctx.fillRect(0, 80, canvasWidth, 8);

    // Header Text
    ctx.fillStyle = "#ffffff";
    ctx.font = "bold 44px Arial, sans-serif";
    ctx.textAlign = "left";
    ctx.textBaseline = "alphabetic";
    ctx.fillText("NEW YORK STATE", 30, 56);

    ctx.font = "bold 16px Arial";
    ctx.fillText("DRIVER LICENSE", 430, 52);

    // 3. Draw Photos
    const drawCroppedPhoto = (img, dx, dy, dw, dh, alpha = 1.0) => {
        const scale = Math.max(dw / img.width, dh / img.height);
        const cw = img.width * scale;
        const ch = img.height * scale;
        const cx = (dw - cw) / 2;
        const cy = (dh - ch) / 2;

        ctx.save();
        ctx.globalAlpha = alpha;
        ctx.beginPath();
        ctx.rect(dx, dy, dw, dh);
        ctx.clip();
        ctx.drawImage(img, dx + cx, dy + cy, cw, ch);
        ctx.restore();
    };

    // Main Photo (Left)
    const photoWidth = 210;
    const photoHeight = 280;
    const photoX = 30;
    const photoY = 110;
    
    // Slight shadow and border for main photo
    ctx.shadowColor = "rgba(0,0,0,0.3)";
    ctx.shadowBlur = 8;
    ctx.shadowOffsetX = 3;
    ctx.shadowOffsetY = 3;
    ctx.fillStyle = "#ffffff";
    ctx.fillRect(photoX - 2, photoY - 2, photoWidth + 4, photoHeight + 4);
    ctx.shadowColor = "transparent"; // Reset shadow

    drawCroppedPhoto(originalImg, photoX, photoY, photoWidth, photoHeight, 1.0);

    // Ghost Photo (Right)
    drawCroppedPhoto(originalImg, 680, 290, 130, 173, 0.35);

    // 4. Draw Data Fields
    // Helper function mapped to realistic NY layout
    const drawField = (num, label, val, x, y, valYOffset = 18, highlightVal = false) => {
        ctx.textAlign = "left";
        
        // Number indicator
        ctx.fillStyle = "#a81818"; // Cardinal red
        ctx.font = "bold 11px Arial";
        ctx.fillText(num, x, y);

        // Label
        ctx.fillStyle = "#0c2340"; // Navy blue
        ctx.font = "bold 10px Arial";
        ctx.fillText(label, x + 16, y);

        // Value
        ctx.fillStyle = highlightVal ? "#a81818" : "#000000";
        if (num === "1" || num === "2") {
            ctx.font = "bold 22px Arial"; // Name is larger
        } else if (num === "9") {
            ctx.font = "bold 20px Arial"; // ID is larger
        } else {
            ctx.font = "bold 16px Arial"; 
        }
        ctx.fillText(val, x + 16, y + valYOffset);
    };

    // Client ID & DOB row
    drawField("9", "ID", idNumber, 270, 130);
    drawField("3", "DOB", dob, 520, 130, 18, true); // DOB is often highlighted red

    // Document Class
    drawField("9a", "Class", documentClass, 720, 130);

    // Name
    drawField("1,2", "Name", name, 270, 190, 22);

    // Address
    // Custom multiline draw for address
    ctx.fillStyle = "#a81818";
    ctx.font = "bold 11px Arial";
    ctx.fillText("8", 270, 255);
    ctx.fillStyle = "#0c2340";
    ctx.font = "bold 10px Arial";
    ctx.fillText("Address", 286, 255);
    
    ctx.fillStyle = "#000000";
    ctx.font = "bold 16px Arial";
    ctx.fillText(address1, 286, 273);
    ctx.fillText(address2, 286, 292);

    // Physical Traits Row
    drawField("15", "Sex", sex, 270, 340);
    drawField("16", "Ht", heightVal, 340, 340); // Updated to use renamed parameter to resolve global namespace conflict
    drawField("17", "Eye", eyes, 420, 340);

    // Dates Row
    drawField("4a", "ISS", issueDate, 270, 395);
    drawField("4b", "EXP", expDate, 420, 395, 18, true);

    // Restrictions / Endorsements
    drawField("12", "REST", "NONE", 270, 450);
    drawField("9b", "ENDORSE", "NONE", 420, 450);

    // 5. Signature
    ctx.fillStyle = "#111111";
    ctx.font = '42px "Caveat", cursive';
    ctx.textAlign = "center";
    
    // Randomize signature angle slightly for realism
    ctx.save();
    ctx.translate(460, 490);
    ctx.rotate( -0.03 ); // Slight upward tilt
    ctx.fillText(name, 0, 0);
    ctx.restore();

    // 6. Barcode Substitute (Front 2D mark often present in some IDs as a minor element)
    // We'll draw a simulated small 2D square matrix
    ctx.fillStyle = "#000000";
    const qrX = 30;
    const qrY = 410;
    const qrSize = 60;
    // Draw pseudo-random tiny blocks
    for(let r=0; r<qrSize; r+=4) {
        for(let c=0; c<qrSize; c+=4) {
            // Predictable pseudo-random to keep output consistent
            if ((r * 11 + c * 7) % 3 === 0 || (r<12 && c<12) || (r>qrSize-12 && c<12) || (r<12 && c>qrSize-12)) {
                ctx.fillRect(qrX + c, qrY + r, 4, 4);
            }
        }
    }
    
    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

This tool allows you to generate a customized visual representation of a New York State-style driver’s license. Users can upload a photo and input specific personal details such as name, ID number, date of birth, address, and physical characteristics to be overlaid onto a stylized ID card template. This can be used for creative projects, graphic design mockups, or as a placeholder in digital layouts.

Leave a Reply

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