Please bookmark this page to avoid losing your image tool!

California Driver’s License Photorealistic 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, 
    idNum = "D7658681", 
    expDate = "03/30/2029", 
    dobDate = "03/30/1969", 
    lastName = "STEWART", 
    firstName = "RONALD", 
    addressLine1 = "10 PELICAN CT", 
    addressLine2 = "SACRAMENTO, CA 95833", 
    sexStat = "M", 
    hairStat = "BRN", 
    eyeStat = "BRO", 
    hgtStat = "5-06", 
    wgtStat = "142", 
    classStat = "C"
) {
    // 1. Load Custom Fonts Dynamically
    await new Promise(resolve => {
        const link = document.createElement('link');
        link.href = 'https://fonts.googleapis.com/css2?family=Caveat:wght@700&family=Pacifico&display=swap';
        link.rel = 'stylesheet';
        document.head.appendChild(link);
        
        // Wait till fonts are parsed and ready
        if (document.fonts) {
            document.fonts.ready.then(() => setTimeout(resolve, 300));
        } else {
            setTimeout(resolve, 1000); // Fallback timeout for older browsers
        }
    });

    // 2. Setup Canvas and Hard Edge Crop (Rounded Card Effect)
    const canvas = document.createElement("canvas");
    canvas.width = 800;
    canvas.height = 500;
    const ctx = canvas.getContext("2d");

    function drawRoundRectCenter(ctx, x, y, w, h, r) {
        ctx.beginPath();
        ctx.moveTo(x + r, y);
        ctx.lineTo(x + w - r, y);
        ctx.quadraticCurveTo(x + w, y, x + w, y + r);
        ctx.lineTo(x + w, y + h - r);
        ctx.quadraticCurveTo(x + w, y + h, x + w - r, y + h);
        ctx.lineTo(x + r, y + h);
        ctx.quadraticCurveTo(x, y + h, x, y + h - r);
        ctx.lineTo(x, y + r);
        ctx.quadraticCurveTo(x, y, x + r, y);
        ctx.closePath();
    }
    
    // Clip the entirety of the canvas to a rounded card layout
    drawRoundRectCenter(ctx, 0, 0, 800, 500, 20);
    ctx.clip();

    // 3. Guilloche Background Pattern Generation
    const bgGrad = ctx.createLinearGradient(0, 0, 800, 500);
    bgGrad.addColorStop(0, "#d5e8f7"); // light blue
    bgGrad.addColorStop(0.5, "#fcf2d9"); // light yellow
    bgGrad.addColorStop(1, "#d5e8f7"); // light blue
    ctx.fillStyle = bgGrad;
    ctx.fillRect(0, 0, 800, 500);

    function drawGuilloche(ctx, yOffset, amplitude, freq, color, phases) {
        ctx.beginPath();
        ctx.strokeStyle = color;
        ctx.lineWidth = 1;
        for (let x = 0; x <= 800; x += 2) {
            let y = yOffset;
            phases.forEach(p => {
                y += Math.sin(x * p.f + p.p) * p.a;
            });
            if (x === 0) ctx.moveTo(x, y);
            else ctx.lineTo(x, y);
        }
        ctx.stroke();
    }

    // Overlapping wavy guilloche security lines
    for (let i = 0; i < 80; i++) {
        const color = i % 3 === 0 ? "rgba(255,255,255,0.7)" : i % 3 === 1 ? "rgba(180,210,240,0.5)" : "rgba(250,240,180,0.5)";
        const phases = [
            { f: 0.01, a: 30, p: i * 0.1 },
            { f: 0.03, a: 15, p: i * 0.2 },
            { f: 0.005, a: 60, p: i * 0.05 }
        ];
        drawGuilloche(ctx, (i / 80) * 500, 0, 0, color, phases);
    }
    for (let i = 0; i < 20; i++) {
        drawGuilloche(ctx, 250, 0, 0, "rgba(255, 255, 255, 0.4)", [
            { f: 0.015, a: 150, p: i * 0.3 },
            { f: 0.02, a: -40, p: i * 0.1 }
        ]);
    }

    // Utility handler mimicking `object-fit: cover`
    function drawCover(ctx, img, x, y, w, h) {
        const imgRatio = img.width / img.height;
        const boxRatio = w / h;
        let sx = 0, sy = 0, sWidth = img.width, sHeight = img.height;
        if (imgRatio > boxRatio) {
            sWidth = img.height * boxRatio;
            sx = (img.width - sWidth) / 2;
        } else {
            sHeight = img.width / boxRatio;
            sy = (img.height - sHeight) / 2;
        }
        ctx.drawImage(img, sx, sy, sWidth, sHeight, x, y, w, h);
    }

    // 4. Ghost Photo Bottom Right (softly blended, faded, zero harsh borders via radial gradient mask)
    const tmpCanvas = document.createElement("canvas");
    tmpCanvas.width = 800;
    tmpCanvas.height = 500;
    const tmpCtx = tmpCanvas.getContext("2d");

    tmpCtx.filter = "grayscale(50%) opacity(60%) contrast(150%)"; // Standard faded ID styling
    drawCover(tmpCtx, originalImg, 590, 240, 160, 215);
    tmpCtx.filter = "none";

    tmpCtx.globalCompositeOperation = "destination-in";
    const gx = 590 + 80;
    const gy = 240 + 107;
    const gGrad = tmpCtx.createRadialGradient(gx, gy, 10, gx, gy, 100);
    gGrad.addColorStop(0, "rgba(0,0,0,1)");
    gGrad.addColorStop(1, "rgba(0,0,0,0)");
    tmpCtx.fillStyle = gGrad;
    tmpCtx.fillRect(480, 130, 350, 450); // Large bounding box to not limit radial gradient falloff

    ctx.drawImage(tmpCanvas, 0, 0);

    // 5. Main Photo Left Bound
    ctx.save();
    drawRoundRectCenter(ctx, 35, 125, 240, 310, 5); 
    ctx.clip();
    drawCover(ctx, originalImg, 35, 125, 240, 310);
    ctx.restore();

    // 6. Bold Headers ("California", "USA", "DRIVER LICENSE")
    ctx.fillStyle = "#2a59a6";
    ctx.font = "bold 20px Arial, sans-serif";
    ctx.fillText("USA", 45, 40);
    ctx.font = "normal 55px 'Pacifico', cursive, sans-serif";
    ctx.fillText("California", 95, 75);
    ctx.font = "bold 16px Arial, sans-serif";
    ctx.fillText("DRIVER LICENSE", 115, 105);

    // 7. Golden California Grizzly Bear Emblem (Top Right)
    ctx.save();
    ctx.translate(650, 20); 
    ctx.scale(2.5, 2.5); 
    const bearSvg = "M49.6,27.1c-0.2-1.9-1.9-2.9-3.4-3.1 c-10-1.8-21.7,0.3-25.5,1.1C18,25.6,15,28.6,13.7,29.8c-2,1.8-3.7,1.8-4.9,1.5c-1.3-0.3-2.6-1.5-3.1-2.9C5,25.6,3.6,26,1.4,27.3 c-2.2,1.3-2.8,2.7-2.3,4.4C0.2,35.9,2.4,41.4,5,44.2c2.6,2.8,7,3,9.4,1.4c2.4-1.5,2.4-3.5,2.2-4.1c-0.3-0.8-1.5-1.7-2-1.8 c-0.6-0.1-2.8,0.2-4-0.9c-1.1-1.1-1.1-3,0.3-4.1c0.7-0.5,1.7-0.5,2.7-0.4c1,0.1,2.8,1.4,5,1c5.2-1,8.3-4.5,10-6 c1.7-1.5,4-3.5,6-3.8c2-0.3,5,0.7,6,1c1,0.3,1.3,0.9,1.5,1.4c0.1,0.5,0.4,1.3,0.1,2c-0.3,0.7-1,1.9-2.2,2.7c-1.2,0.8-2,2.3-2.2,3.1 c-0.2,0.9,0.3,2.4,1.4,3.2c1.1,0.8,3,0.6,4.1,0.3c1.5-0.5,2.8-1.7,3-3c0.1-1-0.2-2.3-0.9-3.2C44,31.7,43.2,30.5,44,29 c0.6-1.1,2.6-1.3,3.8-1.3C49,27.7,49.8,28.5,49.6,27.1z";
    ctx.fillStyle = "#cca833";
    ctx.fill(new Path2D(bearSvg));

    // White Star Outset 
    ctx.fillStyle = "#ffffff";
    ctx.beginPath();
    const sx = 25; const sy = 33; const r = 3.5;
    for(let i = 0; i < 5; i++) {
        let ang1 = (Math.PI / 180) * (270 + i * 72); 
        let ang2 = (Math.PI / 180) * (270 + i * 72 + 36);
        let px1 = sx + r * Math.cos(ang1);
        let py1 = sy + r * Math.sin(ang1);
        let px2 = sx + (r / 2.5) * Math.cos(ang2);
        let py2 = sy + (r / 2.5) * Math.sin(ang2);
        if (i === 0) ctx.moveTo(px1, py1);
        else ctx.lineTo(px1, py1);
        ctx.lineTo(px2, py2);
    }
    ctx.closePath();
    ctx.fill();
    ctx.restore();

    // 8. Printed Identifying Card Stats
    const tLeft = 300;
    let yT = 150;

    function drawField(label, value, x, y, valColor = "#000") {
        ctx.font = "12px Arial, sans-serif";
        ctx.fillStyle = "#555";
        ctx.fillText(label, x, y - 16);
        ctx.font = "bold 20px Arial, sans-serif";
        ctx.fillStyle = valColor;
        ctx.fillText(value, x, y);
    }

    ctx.font = "bold 22px Arial, sans-serif";
    ctx.fillStyle = "#d32228"; // Red requirement
    ctx.fillText("ID  " + idNum, tLeft, yT);

    yT += 45;
    ctx.fillText("DOB " + dobDate, tLeft, yT);
    ctx.fillText("EXP " + expDate, tLeft + 180, yT);

    yT += 50;
    drawField("LN", lastName, tLeft, yT);
    yT += 45;
    drawField("FN", firstName, tLeft, yT);

    yT += 45;
    ctx.font = "12px Arial, sans-serif";
    ctx.fillStyle = "#555";
    ctx.fillText("ADDRESS", tLeft, yT - 16);
    ctx.font = "bold 18px Arial, sans-serif";
    ctx.fillStyle = "#000";
    ctx.fillText(addressLine1, tLeft, yT);
    ctx.fillText(addressLine2, tLeft, yT + 22);

    yT += 55;
    function drawStat(label, val, offsetX) {
        ctx.font = "10px Arial, sans-serif";
        ctx.fillStyle = "#555";
        ctx.fillText(label, tLeft + offsetX, yT - 15);
        ctx.font = "bold 16px Arial, sans-serif";
        ctx.fillStyle = "#000";
        ctx.fillText(val, tLeft + offsetX, yT);
    }
    drawStat("SEX", sexStat, 0);
    drawStat("HAIR", hairStat, 45);
    drawStat("EYES", eyeStat, 105);
    drawStat("HGT", hgtStat, 165);
    drawStat("WGT", wgtStat, 225);
    drawStat("CLASS", classStat, 285);

    // 9. Cursive Signature Overlap (Bottom Center)
    ctx.textAlign = "center";
    ctx.font = "bold 35px 'Caveat', cursive, sans-serif";
    ctx.fillStyle = "#111111"; // Realistically dark black ink 
    ctx.fillText(firstName + " " + lastName, 530, 440);
    ctx.textAlign = "left"; 

    // 10. Accurate Linear Scannable Barcode (Bottom Edge)
    ctx.fillStyle = "#000000";
    let bX = 290;
    while (bX <= 750) {
        let w = Math.random() * 3 + 1; // Variation ranging 1 to 4px widths
        if (bX + w > 750) w = 750 - bX;
        ctx.fillRect(bX, 470, w, 20); // Pinched to the extreme solid bottom offset
        bX += w + Math.random() * 3 + 1.5; // Natural scanner spacing logic
    }

    // Standard DOM Canvas export ready for final viewport insertion
    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 generates a photorealistic representation of a California Driver’s License by overlaying custom personal information onto an uploaded image. It uses advanced canvas rendering techniques to apply security features like guilloche background patterns, a faded ‘ghost photo’ effect, and a scannable barcode. Users can customize various identity fields including name, ID number, date of birth, expiration date, address, and physical characteristics. This utility can be used for creative projects, graphic design mockups, or theatrical prop creation.

Leave a Reply

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