Please bookmark this page to avoid losing your image tool!

Image To California Driver’s License 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.
function processImage(originalImg, name = "Cesar Rodriguez", dob = "11/2/1973", address = "890 SAWTELLE Ave San diego Ca 92114") {
    const canvas = document.createElement('canvas');
    const width = 600;
    const height = 380;
    canvas.width = width;
    canvas.height = height;
    const ctx = canvas.getContext('2d');

    // Helper: Clip a rounded rectangle path
    function roundRectClip(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();
    }

    // Helper: Draw image with cover fill style
    function customDrawImageCover(ctx, img, x, y, w, h) {
        let imgRatio = img.width / img.height;
        let targetRatio = w / h;
        let srcX = 0, srcY = 0, srcW = img.width, srcH = img.height;

        if (imgRatio > targetRatio) {
            srcW = img.height * targetRatio;
            srcX = (img.width - srcW) / 2;
        } else {
            srcH = img.width / targetRatio;
            srcY = (img.height - srcH) / 2;
        }
        ctx.drawImage(img, srcX, srcY, srcW, srcH, x, y, w, h);
    }

    // Helper: Wrap text for Address
    function wrapTextAndReturnY(ctx, text, x, y, maxWidth, lineHeight) {
        let words = text.split(' ');
        let line = '';
        for (let n = 0; n < words.length; n++) {
            let testLine = line + words[n] + ' ';
            let metrics = ctx.measureText(testLine);
            let testWidth = metrics.width;
            if (testWidth > maxWidth && n > 0) {
                ctx.fillText(line.trim(), x, y);
                line = words[n] + ' ';
                y += lineHeight;
            } else {
                line = testLine;
            }
        }
        ctx.fillText(line.trim(), x, y);
        return y + lineHeight;
    }

    // Helper: Draw field with colored label
    function drawField(label, value, xLinesUp, y) {
        ctx.fillStyle = "#1b365d"; // Navy blue label
        ctx.font = "bold 10px Arial, sans-serif";
        ctx.textAlign = "right";
        ctx.fillText(label, xLinesUp, y);

        ctx.fillStyle = "black";
        ctx.font = "bold 14px Arial, sans-serif";
        ctx.textAlign = "left";
        ctx.fillText(value, xLinesUp + 5, y);
    }

    // Helper: Draw geometric star
    function drawStar(ctx, cx, cy, spikes, outerRadius, innerRadius) {
        let rot = Math.PI / 2 * 3;
        let x = cx, 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.lineTo(cx, cy - outerRadius);
        ctx.closePath();
        ctx.fill();
    }

    // Parse Name
    let nameParts = name.trim().split(' ');
    let lastName = nameParts.length > 1 ? nameParts.pop() : "";
    let firstName = nameParts.join(' ');
    if (!lastName) { lastName = firstName; firstName = ""; }

    // 1. Draw Card Shape and Background
    roundRectClip(ctx, 0, 0, width, height, 16);
    ctx.clip(); // Limit drawing bounds to the rounded rectangle

    let grd = ctx.createLinearGradient(0, 0, width, height);
    grd.addColorStop(0, "#f9fcfc");
    grd.addColorStop(0.5, "#e5f0f9");
    grd.addColorStop(1, "#fcf7e8");
    ctx.fillStyle = grd;
    ctx.fillRect(0, 0, width, height);

    // 2. Security Watermarks / Patterns
    ctx.save();
    ctx.translate(300, 190);
    ctx.rotate(-Math.PI / 9);
    ctx.font = "bold 110px Arial, sans-serif";
    ctx.fillStyle = "rgba(255, 255, 255, 0.5)"; // Translucent white watermark
    ctx.textAlign = "center";
    ctx.textBaseline = "middle";
    ctx.fillText("CALIFORNIA", 0, 0);
    ctx.restore();

    ctx.beginPath();
    for (let x = 0; x < width; x += 5) {
        ctx.lineTo(x, 220 + Math.sin(x / 15) * 8);
    }
    ctx.strokeStyle = "rgba(173, 216, 230, 0.3)";
    ctx.lineWidth = 1;
    ctx.stroke();

    // 3. Top Header Divider Bar
    ctx.fillStyle = "#8dc63f";
    ctx.fillRect(0, 85, 200, 3);
    ctx.fillStyle = "#fdb913";
    ctx.fillRect(200, 85, 200, 3);
    ctx.fillStyle = "#0072ce";
    ctx.fillRect(400, 85, 200, 3);

    // 4. Header Titles
    ctx.font = "italic bold 45px 'Brush Script MT', 'Lucida Handwriting', 'Apple Chancery', cursive";
    ctx.fillStyle = "#c72027"; // CA Red
    ctx.textAlign = "center";
    ctx.strokeStyle = "white";
    ctx.lineWidth = 4;
    ctx.strokeText("California", 300, 48);
    ctx.fillText("California", 300, 48);

    ctx.font = "bold 16px Arial, sans-serif";
    ctx.fillStyle = "#1b365d";
    ctx.fillText("DRIVER LICENSE", 300, 72);

    ctx.font = "bold 12px Arial, sans-serif";
    ctx.fillText("USA", 550, 25);

    // 5. Real ID Star (Top Right)
    ctx.fillStyle = "#d4af37"; // Gold
    ctx.beginPath();
    ctx.arc(550, 55, 16, 0, Math.PI * 2);
    ctx.fill();
    ctx.fillStyle = "white";
    drawStar(ctx, 550, 55, 5, 10, 4);

    // 6. Draw Primary Portrait Images
    const imgX = 20, imgY = 105, imgW = 130, imgH = 170;
    ctx.save();
    roundRectClip(ctx, imgX, imgY, imgW, imgH, 10);
    ctx.clip();
    customDrawImageCover(ctx, originalImg, imgX, imgY, imgW, imgH);
    ctx.restore();
    
    // Portrait border
    ctx.strokeStyle = "rgba(27, 54, 93, 0.4)";
    ctx.lineWidth = 2;
    ctx.stroke();

    // 7. Ghost Portrait
    const gX = 480, gY = 240, gW = 90, gH = 115;
    ctx.save();
    ctx.globalAlpha = 0.35;
    roundRectClip(ctx, gX, gY, gW, gH, 8);
    ctx.clip();
    customDrawImageCover(ctx, originalImg, gX, gY, gW, gH);
    ctx.restore();

    // 8. Text Fields Layout (Right-aligned guides at X = 195, 280, 380, etc.)
    const startX = 195;
    drawField("DL", "X" + Math.floor(1000000 + Math.random() * 9000000), startX, 115);
    drawField("EXP", "11/02/2028", 345, 115);
    drawField("CLASS", "C", 495, 115);

    drawField("LN", lastName.toUpperCase(), startX, 140);
    drawField("FN", firstName.toUpperCase(), startX, 165);

    // Address handling
    ctx.fillStyle = "black";
    ctx.font = "bold 14px Arial, sans-serif";
    ctx.textAlign = "left";
    let yAfterAddress = wrapTextAndReturnY(ctx, address.toUpperCase(), startX + 5, 190, 275, 18);

    // DOB
    let dobY = yAfterAddress + 15;
    ctx.fillStyle = "#1b365d";
    ctx.font = "bold 10px Arial, sans-serif";
    ctx.textAlign = "right";
    ctx.fillText("DOB", startX, dobY);
    ctx.fillStyle = "#c72027"; // Important fields in red
    ctx.font = "bold 16px Arial, sans-serif";
    ctx.textAlign = "left";
    ctx.fillText(dob.toUpperCase(), startX + 5, dobY);

    // Stats Section
    let heightY = dobY + 28;
    drawField("SEX", "M", startX, heightY);
    drawField("HAIR", "BLK", 280, heightY);
    drawField("EYES", "BRN", 380, heightY);

    let infoY2 = heightY + 25;
    drawField("HGT", "5'-08\"", startX, infoY2);
    drawField("WGT", "165 lb", 280, infoY2);
    drawField("ISS", "08/14/2023", 380, infoY2);

    // 9. Signature
    ctx.font = "32px 'Brush Script MT', 'Lucida Handwriting', 'Apple Chancery', cursive";
    ctx.fillStyle = "black";
    ctx.textAlign = "center";
    ctx.textBaseline = "middle";
    // Place roughly between the portrait and the ghost image
    ctx.fillText(name, 315, 350, 270);

    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 overlay a personal photo onto a template designed to resemble a California driver’s license. It automatically populates the template with customizable information such as name, date of birth, and address, while applying various graphical elements like watermarks, security patterns, and signature styles. This tool can be used for creative projects, role-playing games, or as a placeholder for digital identity mockups in design prototypes.

Leave a Reply

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