Please bookmark this page to avoid losing your image tool!

Image Driver’s License Template 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.
function processImage(
    originalImg,
    p_fullName = "JOHN A. DOE",
    p_address = "123 MAIN ST, ANYTOWN, ST 12345",
    p_dateOfBirth = "01/01/1980",
    p_licenseNumber = "A12345678",
    p_issueDate = "01/01/2020",
    p_expiryDate = "01/01/2028",
    p_stateName = "STATE OF EXAMPLE",
    p_licenseClass = "C",
    p_sex = "M",
    p_height = "5'-10\"",
    p_eyeColor = "BLU",
    p_signatureText = "John A. Doe", // If empty, just a line will be drawn
    p_realIdStar = "YES", // "YES" or "NO"
    p_organDonor = "YES"  // "YES" or "NO"
) {
    const W = 600;
    const H = 380;
    const canvas = document.createElement('canvas');
    canvas.width = W;
    canvas.height = H;
    const ctx = canvas.getContext('2d');

    // Helper function to draw a star (for Real ID)
    function _drawStarFS(context, cx, cy, spikes, outerRadius, innerRadius) {
        let rot = Math.PI / 2 * 3;
        let x = cx;
        let y = cy;
        let step = Math.PI / spikes;
        context.beginPath();
        context.moveTo(cx, cy - outerRadius);
        for (let i = 0; i < spikes; i++) {
            x = cx + Math.cos(rot) * outerRadius;
            y = cy + Math.sin(rot) * outerRadius;
            context.lineTo(x, y);
            rot += step;
            x = cx + Math.cos(rot) * innerRadius;
            y = cy + Math.sin(rot) * innerRadius;
            context.lineTo(x, y);
            rot += step;
        }
        context.lineTo(cx, cy - outerRadius);
        context.closePath();
    }

    // 1. Background
    ctx.fillStyle = '#E8F0F8'; // A light, slightly blueish background
    ctx.fillRect(0, 0, W, H);

    // Subtle background grid (placeholder for security patterns)
    ctx.strokeStyle = '#D0D8E0';
    ctx.lineWidth = 0.5;
    for (let i = 0; i < W; i += 10) {
        ctx.beginPath(); ctx.moveTo(i, 0); ctx.lineTo(i, H); ctx.stroke();
    }
    for (let i = 0; i < H; i += 10) {
        ctx.beginPath(); ctx.moveTo(0, i); ctx.lineTo(W, i); ctx.stroke();
    }
    ctx.lineWidth = 1; // Reset line width

    // 2. Header
    ctx.textAlign = 'center';
    ctx.fillStyle = '#003366'; // Dark blue for header
    ctx.font = 'bold 26px Arial';
    ctx.fillText(p_stateName.toUpperCase(), W / 2, 45);
    
    ctx.font = 'bold 18px Arial'; 
    ctx.fillText("DRIVER LICENSE", W / 2, 70);

    // 3. Photo
    const photoX = 30;
    const photoY = 90;
    const photoWidth = 100;
    const photoHeight = 125;
    if (originalImg && originalImg.complete && originalImg.naturalWidth !== 0) {
        try {
            ctx.drawImage(originalImg, photoX, photoY, photoWidth, photoHeight);
        } catch (e) {
            console.error("Error drawing image:", e);
             // Draw a placeholder if image drawing fails
            ctx.fillStyle = '#CCCCCC';
            ctx.fillRect(photoX, photoY, photoWidth, photoHeight);
            ctx.fillStyle = '#888888';
            ctx.font = '12px Arial';
            ctx.textAlign = 'center';
            ctx.fillText("Photo Error", photoX + photoWidth/2, photoY + photoHeight/2);
        }
    } else { 
        ctx.fillStyle = '#CCCCCC';
        ctx.fillRect(photoX, photoY, photoWidth, photoHeight);
        ctx.fillStyle = '#888888';
        ctx.font = '12px Arial';
        ctx.textAlign = 'center';
        ctx.fillText("No Photo", photoX + photoWidth/2, photoY + photoHeight/2);
    }
    ctx.strokeStyle = '#333';
    ctx.strokeRect(photoX, photoY, photoWidth, photoHeight);
    ctx.textAlign = 'left'; // Reset textAlign

    // 4. Main Information Block (Right of Photo)
    ctx.fillStyle = 'black';
    const infoX = photoX + photoWidth + 20; 
    let currentY = photoY + 5; 
    const N_lh = 18; 
    const B_lh = 22; 
    const labelWidth = 70; 
    const valueX = infoX + labelWidth;

    // License Number
    ctx.font = '10px Arial';
    ctx.fillText("NUMBER", infoX, currentY);
    ctx.font = 'bold 14px "Courier New", monospace';
    ctx.fillText(String(p_licenseNumber).toUpperCase(), valueX, currentY);
    currentY += B_lh;

    // Full Name
    ctx.font = '10px Arial';
    ctx.fillText("NAME", infoX, currentY);
    ctx.font = 'bold 12px Arial';
    ctx.fillText(String(p_fullName).toUpperCase(), valueX, currentY);
    currentY += B_lh;

    // Address
    ctx.font = '10px Arial';
    ctx.fillText("ADDRESS", infoX, currentY);
    ctx.font = '10px Arial'; 
    const addressLines = String(p_address).toUpperCase().split(',');
    let addrLineY = currentY;
    if (addressLines.length > 0 && addressLines[0].trim() !== "") {
        ctx.fillText(addressLines[0].trim(), valueX, addrLineY);
         if (addressLines.length > 1 && addressLines.slice(1).join(',').trim() !== "") {
            addrLineY += N_lh - 4; 
            ctx.fillText(addressLines.slice(1).join(',').trim(), valueX, addrLineY);
        }
    }
    currentY = addrLineY + N_lh;

    // Date of Birth
    ctx.font = '10px Arial';
    ctx.fillText("DOB", infoX, currentY);
    ctx.font = '12px Arial';
    ctx.fillText(String(p_dateOfBirth), valueX, currentY);
    currentY += N_lh;
    
    // Issue Date
    ctx.font = '10px Arial';
    ctx.fillText("ISS", infoX, currentY);
    ctx.font = '12px Arial';
    ctx.fillText(String(p_issueDate), valueX, currentY);
    currentY += N_lh;

    // Expiry Date
    ctx.font = '10px Arial';
    ctx.fillText("EXP", infoX, currentY);
    ctx.font = '12px Arial';
    ctx.fillText(String(p_expiryDate), valueX, currentY);

    // 5. Physical Descriptors and Class (Below Photo)
    let physDescY = photoY + photoHeight + 18; 
    const physDescX = photoX;
    const physColWidth = 75; 
    const physValOffset = 30; 

    ctx.font = '10px Arial'; 
    ctx.fillText("SEX", physDescX, physDescY);
    ctx.font = '12px Arial'; 
    ctx.fillText(String(p_sex).toUpperCase(), physDescX + physValOffset, physDescY);

    ctx.font = '10px Arial';
    ctx.fillText("HGT", physDescX + physColWidth, physDescY);
    ctx.font = '12px Arial';
    ctx.fillText(String(p_height).toUpperCase(), physDescX + physColWidth + physValOffset, physDescY);
    
    ctx.font = '10px Arial';
    ctx.fillText("EYES", physDescX + physColWidth*2, physDescY);
    ctx.font = '12px Arial';
    ctx.fillText(String(p_eyeColor).toUpperCase(), physDescX + physColWidth*2 + physValOffset, physDescY);
    physDescY += N_lh;

    ctx.font = '10px Arial';
    ctx.fillText("CLASS", physDescX, physDescY);
    ctx.font = '12px Arial';
    ctx.fillText(String(p_licenseClass).toUpperCase(), physDescX + physValOffset, physDescY);

    if (String(p_organDonor).toUpperCase() === "YES") {
        ctx.fillStyle = 'red';
        ctx.font = 'bold 11px Arial';
        ctx.fillText("❤ ORGAN DONOR", physDescX + physColWidth -5 , physDescY);
        ctx.fillStyle = 'black'; 
    }

    // 6. Signature Area
    const sigLineY = H - 50;
    const sigXstart = photoX;
    const sigXend = infoX + 180; 
    const sigTextY = sigLineY - 7;

    ctx.beginPath();
    ctx.moveTo(sigXstart, sigLineY);
    ctx.lineTo(sigXend, sigLineY);
    ctx.strokeStyle = 'black';
    ctx.lineWidth = 1;
    ctx.stroke();

    if (p_signatureText && String(p_signatureText).trim() !== "") {
        ctx.font = "italic 18px 'Segoe Script', cursive"; 
        ctx.fillStyle = '#102040'; 
        ctx.textAlign = 'left';
        ctx.fillText(String(p_signatureText), sigXstart + 5, sigTextY);
    }
    ctx.font = '8px Arial';
    ctx.fillStyle = 'black';
    ctx.textAlign = 'center';
    ctx.fillText("SIGNATURE", (sigXstart + sigXend) / 2, sigLineY + 10);
    ctx.textAlign = 'left'; 

    // 7. Ghost Photo
    const ghWidth = 45;
    const ghHeight = 55;
    const ghX = W - ghWidth - 30;
    const ghY = H - ghHeight - 60; 
    
    if (originalImg && originalImg.complete && originalImg.naturalWidth !== 0) {
        try {
            ctx.globalAlpha = 0.35;
            ctx.drawImage(originalImg, ghX, ghY, ghWidth, ghHeight);
            ctx.globalAlpha = 1.0;
        } catch (e) {
            ctx.globalAlpha = 1.0; // Reset alpha if error
             // placeholder for ghost photo error
        }
    }
    ctx.strokeStyle = '#B0B0B0';
    ctx.lineWidth = 0.5;
    ctx.strokeRect(ghX, ghY, ghWidth, ghHeight);
    ctx.lineWidth = 1; 

    // 8. Real ID Star 
    if (String(p_realIdStar).toUpperCase() === "YES") {
        const starCenterX = W - 40;
        const starCenterY = 40; 
        const starOuterRadius = 13;
        const starInnerRadius = 5;
        
        ctx.beginPath();
        ctx.arc(starCenterX, starCenterY, starOuterRadius, 0, 2 * Math.PI, false);
        ctx.fillStyle = '#FFD700'; 
        ctx.fill();

        ctx.fillStyle = 'white'; 
        _drawStarFS(ctx, starCenterX, starCenterY,  5, starOuterRadius * 0.85, starInnerRadius * 0.8);
        ctx.fill();
    }
    
    // Footer text
    ctx.font = 'bold 8px Arial';
    ctx.fillStyle = '#555555';
    ctx.textAlign = 'right'; 
    const footerText = String(p_stateName).split(" ").map(s => s[0]).join("") + "-ID";
    ctx.fillText(footerText.toUpperCase(), W - 15, H - 15); 
    ctx.textAlign = 'left'; 
    
    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 Image Driver’s License Template Creator is an online tool designed to generate realistic driver’s license templates by inputting user-specific details such as name, address, date of birth, license number, and more. It allows users to upload a photo and customize various attributes including license class, gender, height, eye color, and organ donor status. This tool can be particularly useful for creating mock-up IDs for training, educational purposes, or design previews. Additionally, it features elements like a Real ID star, signature area, and customizable backgrounds, providing users with a comprehensive license template suitable for various mock scenarios.

Leave a Reply

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