Please bookmark this page to avoid losing your image tool!

California State Driver License Image 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,
    firstName = "JOHN",
    lastName = "DOE",
    dob = "01/01/1990",
    exp = "01/01/2028",
    dlNumber = "Z1234567",
    addressL1 = "123 FAKE STREET",
    addressL2 = "LOS ANGELES, CA 90028",
    sex = "M",
    hair = "BRN",
    eyes = "BRN",
    hgt = "5'-10\"",
    wgt = "160 lb",
    issDate = "01/01/2023"
) {
    const canvas = document.createElement("canvas");
    canvas.width = 800;
    canvas.height = 504;
    const ctx = canvas.getContext("2d");

    // Load signature font dynamically
    try {
        const fontName = "Caveat";
        const link = document.createElement("link");
        link.href = `https://fonts.googleapis.com/css2?family=${fontName}:wght@700&display=swap`;
        link.rel = "stylesheet";
        document.head.appendChild(link);
        await document.fonts.load(`700 40px '${fontName}'`);
    } catch (e) {
        // Silently fail and fallback to standard cursive fonts
    }

    // 1. Background Gradient Base
    const bgGrad = ctx.createLinearGradient(0, 0, 800, 504);
    bgGrad.addColorStop(0, "#e8fbff");
    bgGrad.addColorStop(0.5, "#fffdf2");
    bgGrad.addColorStop(1, "#f2ecf9");
    ctx.fillStyle = bgGrad;
    ctx.fillRect(0, 0, canvas.width, canvas.height);

    // 2. Guilloche Security Wavy Lines
    ctx.save();
    ctx.globalAlpha = 0.15;
    ctx.lineWidth = 1;
    for (let y = -50; y < 550; y += 15) {
        ctx.strokeStyle = y % 30 === 0 ? "#003a70" : "#a82046";
        ctx.beginPath();
        for (let x = 0; x <= 800; x += 10) {
            let wave = Math.sin((x + y) * 0.02) * 5 + Math.cos(x * 0.05) * 3;
            if (x === 0) ctx.moveTo(x, y + wave);
            else ctx.lineTo(x, y + wave);
        }
        ctx.stroke();
    }
    ctx.restore();

    // 3. Faded Golden California State Map Overlay
    ctx.save();
    ctx.globalAlpha = 0.2;
    const mapGrad = ctx.createLinearGradient(200, 0, 600, 500);
    mapGrad.addColorStop(0, "#ffd700");
    mapGrad.addColorStop(1, "#ffa500");
    ctx.fillStyle = mapGrad;
    ctx.beginPath();
    const mapPoints = [
        [300, 30], [420, 30], [420, 140],
        [600, 460], [570, 490], [480, 470],
        [430, 410], [320, 230], [270, 110]
    ];
    ctx.moveTo(mapPoints[0][0], mapPoints[0][1]);
    for (let i = 1; i < mapPoints.length; i++) {
        ctx.lineTo(mapPoints[i][0], mapPoints[i][1]);
    }
    ctx.closePath();
    ctx.fill();
    ctx.restore();

    // Helper functions for drawing
    function roundRectPath(ctx, x, y, width, height, radius) {
        ctx.beginPath();
        ctx.moveTo(x + radius, y);
        ctx.lineTo(x + width - radius, y);
        ctx.quadraticCurveTo(x + width, y, x + width, y + radius);
        ctx.lineTo(x + width, y + height - radius);
        ctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height);
        ctx.lineTo(x + radius, y + height);
        ctx.quadraticCurveTo(x, y + height, x, y + height - radius);
        ctx.lineTo(x, y + radius);
        ctx.quadraticCurveTo(x, y, x + radius, y);
        ctx.closePath();
    }

    function drawCover(ctx, img, x, y, w, h) {
        const imgRatio = img.width / img.height;
        const canvasRatio = w / h;
        let renderW, renderH, offsetX = 0, offsetY = 0;
        
        if (imgRatio < canvasRatio) {
            renderW = w;
            renderH = w / imgRatio;
            offsetY = (renderH - h) / 2;
        } else {
            renderH = h;
            renderW = h * imgRatio;
            offsetX = (renderW - w) / 2;
        }
        
        ctx.drawImage(img, x - offsetX, y - offsetY, renderW, renderH);
    }

    function label(text, x, y, color = "#a82046") {
        ctx.font = "11px Arial";
        ctx.fillStyle = color;
        ctx.fillText(text, x, y);
    }

    function val(text, x, y, font = "bold 16px Arial", color = "black", maxW = null) {
        ctx.font = font;
        ctx.fillStyle = color;
        if (maxW) ctx.fillText(text, x, y, maxW);
        else ctx.fillText(text, x, y);
    }

    // 4. Header Bar and Top Text
    ctx.fillStyle = "rgba(100, 180, 240, 0.15)";
    ctx.fillRect(0, 0, 800, 80);

    ctx.fillStyle = "#194a8d";
    ctx.font = "italic bold 44px 'Georgia', 'Times New Roman', serif";
    ctx.fillText("California", 240, 52);

    val("USA", 520, 35, "bold 16px Arial", "#a82046");
    val("DRIVER LICENSE", 270, 75, "bold 16px Arial", "black");

    // 5. Photos (Main and Ghost)
    // Main Photo
    ctx.save();
    roundRectPath(ctx, 30, 100, 200, 300, 10);
    ctx.clip();
    drawCover(ctx, originalImg, 30, 100, 200, 300);
    ctx.restore();
    
    // Photo border
    ctx.save();
    roundRectPath(ctx, 30, 100, 200, 300, 10);
    ctx.lineWidth = 1;
    ctx.strokeStyle = "rgba(0,0,0,0.3)";
    ctx.stroke();
    ctx.restore();

    // Ghost Photo
    ctx.save();
    ctx.filter = "grayscale(100%) opacity(35%)"; // Makes it look authentically printed
    roundRectPath(ctx, 630, 250, 120, 160, 5);
    ctx.clip();
    drawCover(ctx, originalImg, 630, 250, 120, 160);
    ctx.restore();

    // Faded DOB over Ghost image
    ctx.save();
    ctx.font = "bold 18px Arial";
    ctx.fillStyle = "rgba(168, 32, 70, 0.5)";
    ctx.translate(690, 330);
    ctx.rotate(-Math.PI / 6);
    ctx.textAlign = "center";
    ctx.fillText(dob, 0, 0);
    ctx.restore();

    // 6. Detailed Text Fields
    // Identification
    label("DL", 270, 100, "#194a8d");
    val(dlNumber, 295, 100, "bold 20px Arial", "black", 200);

    label("EXP", 530, 100, "#a82046");
    val(exp, 565, 100, "bold 20px Arial", "#a82046");

    // Identifying Data
    label("LN", 270, 140, "#a82046");
    val(lastName, 295, 140, "bold 22px Arial", "black", 400);

    label("FN", 270, 180, "#a82046");
    val(firstName, 295, 180, "bold 22px Arial", "black", 400);

    // Address
    val(addressL1, 295, 215, "16px Arial", "black", 450);
    val(addressL2, 295, 240, "16px Arial", "black", 450);

    // Date of Birth
    label("DOB", 270, 295, "#a82046");
    val(dob, 310, 295, "bold 24px Arial", "#a82046");

    // Physical Attributes row 1
    let lineY = 345;
    label("ISS", 270, lineY, "#194a8d"); val(issDate, 295, lineY, "bold 14px Arial");
    label("SEX", 390, lineY, "#194a8d"); val(sex, 420, lineY, "bold 14px Arial");
    label("HAIR", 455, lineY, "#194a8d"); val(hair, 490, lineY, "bold 14px Arial");
    label("EYES", 540, lineY, "#194a8d"); val(eyes, 580, lineY, "bold 14px Arial");

    // Physical Attributes row 2
    let lineY2 = 380;
    label("HGT", 270, lineY2, "#194a8d"); val(hgt, 300, lineY2, "bold 14px Arial");
    label("WGT", 370, lineY2, "#194a8d"); val(wgt, 405, lineY2, "bold 14px Arial");
    label("CLASS", 475, lineY2, "#194a8d"); val("C", 525, lineY2, "bold 14px Arial");

    // 7. Signature Line & Signature
    ctx.beginPath();
    ctx.moveTo(270, 470);
    ctx.lineTo(750, 470);
    ctx.lineWidth = 1;
    ctx.strokeStyle = "rgba(0,0,0,0.5)";
    ctx.stroke();

    ctx.font = "700 40px 'Caveat', 'Brush Script MT', 'Bradley Hand', 'Comic Sans MS', cursive";
    ctx.fillStyle = "#101010";
    ctx.fillText(`${firstName} ${lastName}`, 300, 465, 450);

    // 8. Design Motifs (REAL ID, Donor Dot, Barcode)
    // REAL ID Golden Star
    ctx.beginPath();
    ctx.arc(740, 50, 22, 0, Math.PI * 2);
    ctx.fillStyle = "#d4af37";
    ctx.fill();
    ctx.fillStyle = "#ffffff";
    ctx.font = "24px Arial";
    ctx.textAlign = "center";
    ctx.textBaseline = "middle";
    ctx.fillText("★", 740, 52); 

    // Pink Donor
    ctx.beginPath();
    ctx.arc(740, 440, 18, 0, Math.PI * 2);
    ctx.fillStyle = "#ffc0cb";
    ctx.fill();
    ctx.fillStyle = "black";
    ctx.font = "bold 9px Arial";
    ctx.fillText("DONOR", 740, 440);
    
    ctx.textAlign = "left";
    ctx.textBaseline = "alphabetic";

    // Bottom Decorative Barcode Element
    ctx.fillStyle = "rgba(0,0,0,0.7)";
    let bx = 30;
    while (bx < 400) {
        let bw = Math.random() > 0.5 ? 2 : (Math.random() > 0.5 ? 3 : 1);
        let gap = Math.random() * 3 + 1;
        if (bx + bw > 400) break;
        ctx.fillRect(bx, 485, bw, 10);
        bx += bw + gap;
    }

    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 users to generate a stylized image of a California State Driver License by overlaying personal information and a profile photo onto a custom-designed template. Users can input various details such as name, date of birth, expiration date, driver’s license number, address, and physical attributes to populate the layout. The tool simulates security features like background gradients, wavy line patterns, and a ghosted image overlay. It can be used for creative projects, role-playing scenarios, or as a placeholder for graphic design mockups.

Leave a Reply

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