Please bookmark this page to avoid losing your image tool!

Washington State Identification Card 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.
function processImage(
    originalImg,
    idNumber = "WDL123456789",
    lastName = "DOE",
    firstName = "JANE SMITH",
    dob = "01/01/1990",
    expDate = "01/01/2028",
    issueDate = "01/01/2023",
    addressLine1 = "123 CHERRY BLOSSOM LN",
    addressLine2 = "OLYMPIA, WA 98501",
    sex = "F",
    height = "5-06",
    weight = "130",
    eyes = "BRN",
    hair = "BLK",
    donor = "Y"
) {
    // Standard ID Card Dimensions ~CR80, upscaled for clarity
    const width = 950;
    const height_px = 600;
    
    const canvas = document.createElement("canvas");
    canvas.width = width;
    canvas.height = height_px;
    const ctx = canvas.getContext("2d");

    // 1. Background Gradient (Pastel Peach to Mint Green to Light Blue)
    const bgGrad = ctx.createLinearGradient(0, 0, width, height_px);
    bgGrad.addColorStop(0, "#fee9db");
    bgGrad.addColorStop(0.5, "#d7ebdd");
    bgGrad.addColorStop(1, "#dde5ed");
    ctx.fillStyle = bgGrad;
    ctx.fillRect(0, 0, width, height_px);

    // 2. Security "Guilloche" Waves Pattern
    ctx.lineWidth = 0.5;
    for (let i = -50; i < height_px + 50; i += 18) {
        ctx.beginPath();
        ctx.moveTo(0, i);
        ctx.bezierCurveTo(300, i - 25, 600, i + 25, width, i);
        ctx.strokeStyle = (i % 36 === 0) ? "rgba(162, 22, 80, 0.06)" : "rgba(10, 58, 112, 0.06)";
        ctx.stroke();
    }

    // 3. Header Mountain Silhouette Background
    ctx.fillStyle = "rgba(10, 58, 112, 0.08)";
    ctx.beginPath();
    ctx.moveTo(0, 160);
    ctx.lineTo(80, 130);
    ctx.lineTo(180, 150);
    ctx.lineTo(350, 90);
    ctx.lineTo(500, 130);
    ctx.lineTo(680, 80);
    ctx.lineTo(820, 110);
    ctx.lineTo(950, 60);
    ctx.lineTo(950, 0);
    ctx.lineTo(0, 0);
    ctx.closePath();
    ctx.fill();

    // 4. Large Yellow "WA" Background Watermark
    ctx.font = "bold 320px Arial";
    ctx.fillStyle = "rgba(255, 215, 0, 0.15)";
    ctx.textAlign = "center";
    ctx.fillText("WA", width / 2 + 100, 450);
    ctx.textAlign = "left";

    // 5. Header Texts
    // "WASHINGTON"
    ctx.font = "bold 58px 'Times New Roman', Times, serif";
    ctx.fillStyle = "#051f4e";
    ctx.fillText("WASHINGTON", 320, 75);

    // "USA"
    ctx.font = "bold 26px Arial, sans-serif";
    ctx.fillStyle = "#051f4e";
    ctx.fillText("USA", 240, 70);

    // "FEDERAL LIMITS APPLY"
    ctx.font = "bold 14px Arial, sans-serif";
    ctx.fillStyle = "#000";
    ctx.fillText("FEDERAL LIMITS APPLY", 750, 40);

    // "IDENTIFICATION CARD" Banner
    ctx.fillStyle = "#A21650"; // Dark Pink commonly used for WA ID (contrasted to Green/Blue for DL)
    ctx.fillRect(320, 85, 450, 36);
    ctx.font = "bold 22px Arial, sans-serif";
    ctx.fillStyle = "#FFF";
    ctx.fillText("IDENTIFICATION CARD", 420, 111);

    // Helper to draw rounded rectangles
    function drawRoundRect(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();
    }

    // 6. Photo Calculations (Maintain Aspect Ratio 3:4)
    const pW = 260;
    const pH = 346;
    const pX = 40;
    const pY = 140;

    let imgW = originalImg.width;
    let imgH = originalImg.height;
    let targetRatio = pW / pH;
    let imgRatio = imgW / imgH;
    let sx, sy, sw, sh;

    if (imgRatio > targetRatio) {
        sh = imgH;
        sw = imgH * targetRatio;
        sx = (imgW - sw) / 2;
        sy = 0;
    } else {
        sw = imgW;
        sh = imgW / targetRatio;
        sx = 0;
        sy = (imgH - sh) / 2;
    }

    // 7. Draw Main Photo
    ctx.save();
    drawRoundRect(pX, pY, pW, pH, 12);
    ctx.clip();
    ctx.drawImage(originalImg, sx, sy, sw, sh, pX, pY, pW, pH);
    ctx.restore();
    
    ctx.strokeStyle = "rgba(0,0,0,0.2)";
    ctx.lineWidth = 1;
    ctx.stroke(); // Draw border for the clipped photo

    // 8. Draw Ghost Photo (Faded, bottom right)
    ctx.save();
    ctx.globalAlpha = 0.35;
    drawRoundRect(740, 340, 160, 213, 8);
    ctx.clip();
    ctx.drawImage(originalImg, sx, sy, sw, sh, 740, 340, 160, 213);
    ctx.restore();

    // 9. Info Fields Setup
    const startX = 330;
    const labelColor = "#A21650"; // WA field labels matching ID pink/red tone
    const valColorText = "#000";
    const valColorRed = "#d41c1c";
    let currY = 175;

    // Helper to draw Label + Text
    function drawLabelAndVal(label, val, x, y, valFont, valColor, spacing = 0) {
        ctx.font = "bold 13px Arial, sans-serif";
        ctx.fillStyle = labelColor;
        ctx.fillText(label, x, y);
        
        ctx.font = valFont;
        ctx.fillStyle = valColor;
        
        // Calculate dynamic spacing if not provided
        if (spacing === 0) {
            spacing = ctx.measureText(label).width + 8;
        }
        ctx.fillText(val, x + spacing, y + (valFont.includes("32px") ? 2 : 1));
    }

    // ID Number (4d)
    ctx.font = "bold 14px Arial, sans-serif";
    ctx.fillStyle = labelColor;
    ctx.fillText("4d", startX, currY);
    ctx.font = "bold 34px Arial, sans-serif";
    ctx.fillStyle = "#051f4e"; // Dark blue for ID number
    ctx.fillText(idNumber, startX + 30, currY + 2);

    // DOB & EXP Row
    currY += 45;
    drawLabelAndVal("3 DOB", dob, startX, currY, "bold 22px Arial", valColorRed, 50);
    drawLabelAndVal("4b EXP", expDate, startX + 220, currY, "bold 22px Arial", valColorRed, 60);

    // Name Fields
    currY += 45;
    drawLabelAndVal("1", lastName, startX, currY, "bold 22px Arial", valColorText, 25);
    currY += 32;
    drawLabelAndVal("2", firstName, startX, currY, "bold 22px Arial", valColorText, 25);

    // Address
    currY += 45;
    ctx.font = "bold 13px Arial"; ctx.fillStyle = labelColor; ctx.fillText("8", startX, currY);
    ctx.font = "bold 18px Arial"; ctx.fillStyle = valColorText;
    ctx.fillText(addressLine1, startX + 25, currY);
    ctx.fillText(addressLine2, startX + 25, currY + 24);

    // Physical Attributes Row
    currY += 75;
    const physLabels = ["15 SEX", "16 HGT", "17 WGT", "18 EYES", "HAIR"];
    const physVals = [sex, height, weight, eyes, hair];
    const physX = [startX, startX + 85, startX + 175, startX + 265, startX + 355];
    
    for (let i = 0; i < 5; i++) {
        ctx.font = "bold 13px Arial";
        ctx.fillStyle = labelColor;
        ctx.fillText(physLabels[i], physX[i], currY);
        
        ctx.font = "bold 19px Arial";
        ctx.fillStyle = valColorText;
        ctx.fillText(physVals[i], physX[i], currY + 26);
    }

    // Issue Date
    currY += 70;
    drawLabelAndVal("4a ISS", issueDate, startX, currY, "bold 18px Arial", valColorText, 55);

    // 10. Donor Status
    if (donor.toUpperCase() === "Y" || donor.toUpperCase() === "YES" || donor.toUpperCase() === "TRUE") {
        ctx.fillStyle = "#D32F2F";
        ctx.font = "40px Arial, sans-serif";
        ctx.fillText("♥", 820, 200);
        ctx.fillStyle = "#000";
        ctx.font = "bold 12px Arial, sans-serif";
        ctx.fillText("DONOR", 813, 222);
    }

    // 11. Fake Barcode & Document Discriminator
    ctx.font = "24px monospace";
    ctx.fillStyle = "#333";
    ctx.fillText("|| ||| | || | ||| ||", 740, 570);
    ctx.font = "12px Arial";
    ctx.fillStyle = "#555";
    ctx.fillText("DD 109283746591029", 740, 585);
    
    // Bottom Left Text
    ctx.font = "bold 10px Arial";
    ctx.fillStyle = labelColor;
    ctx.fillText("WASHINGTON STATE IDENTIFICATION CARD", 30, 585);

    // 12. Signature (Overlapping bottom of the photo)
    ctx.font = "italic 44px 'Brush Script MT', 'Cedarville Cursive', 'Bradley Hand', 'Lucida Handwriting', cursive";
    ctx.fillStyle = "#111"; // Almost black, simulating pen
    let sigText = firstName + " " + lastName;
    // Capitalize first letters only for cursive aesthetics
    sigText = sigText.toLowerCase().replace(/\b\w/g, c => c.toUpperCase());
    
    ctx.save();
    ctx.shadowColor = "rgba(255,255,255,0.7)";
    ctx.shadowBlur = 4;
    // Rotate counter-clockwise slightly for natural flair
    ctx.translate(65, 520);
    ctx.rotate(-0.06); 
    ctx.fillText(sigText, 0, 0);
    ctx.restore();

    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 visual representation of a Washington State Identification Card by overlaying custom text and images onto a formatted template. Users can input personal details such as name, address, date of birth, and physical attributes, and upload a photo to be placed on the card, including a faded ‘ghost’ photo effect. This tool can be used for design mockups, creative projects, or for prototyping identification layouts in various digital media applications.

Leave a Reply

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