Please bookmark this page to avoid losing your image tool!

Image Text Overlay And ID Scanner Tool

(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,
    overlayText = "[ IDENTIFIER SCAN IN PROGRESS ]",
    scannerColor = "#00FF00",
    scanLinePosition = 45,
    overlayOpacity = 0.7
) {
    const canvas = document.createElement('canvas');
    const ctx = canvas.getContext('2d');
    const width = originalImg.width;
    const height = originalImg.height;

    canvas.width = width;
    canvas.height = height;

    // 1. Draw the original image onto the canvas
    ctx.drawImage(originalImg, 0, 0, width, height);

    // 2. Setup ID bounded area (Standard CR80 ID Card ratio 1.586)
    let idWidth = width * 0.8;
    let idHeight = idWidth / 1.586;
    if (idHeight > height * 0.8) {
        idHeight = height * 0.8;
        idWidth = idHeight * 1.586;
    }
    const idX = (width - idWidth) / 2;
    const idY = (height - idHeight) / 2;

    // 3. Draw darkened out-of-bounds overlay
    ctx.fillStyle = `rgba(0, 0, 0, ${Math.max(0, Math.min(1, Number(overlayOpacity)))})`;
    ctx.fillRect(0, 0, width, height);

    // 4. Punch out / Clear the central ID area
    ctx.globalCompositeOperation = 'destination-out';
    ctx.fillStyle = "black";
    ctx.beginPath();
    const cornerRadius = Math.max(5, Math.min(20, width * 0.02));
    if (typeof ctx.roundRect === 'function') {
        ctx.roundRect(idX, idY, idWidth, idHeight, cornerRadius);
    } else {
        ctx.rect(idX, idY, idWidth, idHeight);
    }
    ctx.fill();
    ctx.globalCompositeOperation = 'source-over';

    // 5. Draw scanner bracket corners (Reticle)
    const bracketLen = Math.min(idWidth, idHeight) * 0.15;
    ctx.strokeStyle = scannerColor;
    ctx.lineWidth = Math.max(2, width * 0.008);
    ctx.lineJoin = "round";
    ctx.lineCap = "round";

    // Top-Left Bracket
    ctx.beginPath();
    ctx.moveTo(idX, idY + bracketLen);
    ctx.lineTo(idX, idY);
    ctx.lineTo(idX + bracketLen, idY);
    ctx.stroke();

    // Top-Right Bracket
    ctx.beginPath();
    ctx.moveTo(idX + idWidth - bracketLen, idY);
    ctx.lineTo(idX + idWidth, idY);
    ctx.lineTo(idX + idWidth, idY + bracketLen);
    ctx.stroke();

    // Bottom-Right Bracket
    ctx.beginPath();
    ctx.moveTo(idX + idWidth, idY + idHeight - bracketLen);
    ctx.lineTo(idX + idWidth, idY + idHeight);
    ctx.lineTo(idX + idWidth - bracketLen, idY + idHeight);
    ctx.stroke();

    // Bottom-Left Bracket
    ctx.beginPath();
    ctx.moveTo(idX + bracketLen, idY + idHeight);
    ctx.lineTo(idX, idY + idHeight);
    ctx.lineTo(idX, idY + idHeight - bracketLen);
    ctx.stroke();

    // 6. Draw central targeting crosshair
    ctx.globalAlpha = 0.5;
    ctx.lineWidth = Math.max(1, width * 0.003);
    const cx = idX + idWidth / 2;
    const cy = idY + idHeight / 2;
    const cl = Math.max(10, width * 0.02);
    ctx.beginPath();
    ctx.moveTo(cx - cl, cy);
    ctx.lineTo(cx + cl, cy);
    ctx.moveTo(cx, cy - cl);
    ctx.lineTo(cx, cy + cl);
    ctx.stroke();
    ctx.globalAlpha = 1.0;

    // 7. Draw the Laser Scan Line (position from 0 to 100)
    const pos = Number(scanLinePosition);
    if (pos >= 0 && pos <= 100) {
        const scanPercent = pos / 100;
        const scanY = idY + (idHeight * scanPercent);

        ctx.shadowBlur = Math.max(10, width * 0.01);
        ctx.shadowColor = scannerColor;
        ctx.fillStyle = scannerColor;
        ctx.beginPath();
        ctx.fillRect(idX + 2, scanY - (width * 0.002), idWidth - 4, Math.max(2, width * 0.004));
        ctx.shadowBlur = 0; // reset shadow for later contexts
    }

    // 8. Draw main overlay text above the scanner box
    ctx.fillStyle = scannerColor;
    ctx.font = `bold ${Math.max(16, width * 0.03)}px "Courier New", Courier, monospace`;
    ctx.textAlign = 'center';
    ctx.textBaseline = 'bottom';
    ctx.fillText(overlayText, width / 2, idY - (height * 0.03));

    // Draw camcorder-like recording info in the corners
    ctx.font = `${Math.max(12, width * 0.015)}px "Courier New", Courier, monospace`;
    ctx.textAlign = 'left';
    ctx.textBaseline = 'middle';
    ctx.fillText("REC", width * 0.03, height * 0.04);
    
    // Blinking red dot
    ctx.fillStyle = "red";
    ctx.beginPath();
    // Dot position relative to the REC text
    ctx.arc(width * 0.03 + (width * 0.035), height * 0.04, width * 0.005, 0, Math.PI * 2);
    ctx.fill();

    // Date/Time in top right
    ctx.fillStyle = scannerColor;
    ctx.textAlign = 'right';
    const d = new Date();
    const dateStr = `${d.toISOString().split('T')[0]} ${d.toTimeString().split(' ')[0]}`;
    ctx.fillText(dateStr, width * 0.97, height * 0.04);

    // 9. Try utilizing built-in BarcodeDetector API for an authentic scanner identifier effect
    try {
        if ('BarcodeDetector' in window) {
            const detector = new BarcodeDetector();
            const barcodes = await detector.detect(originalImg);

            ctx.textAlign = 'center';
            ctx.textBaseline = 'top';

            if (barcodes.length > 0) {
                ctx.fillStyle = "#FFFFFF";
                ctx.font = `bold ${Math.max(14, width * 0.02)}px "Courier New", Courier, monospace`;

                let textY = idY + idHeight + (height * 0.03);
                ctx.fillText(">> DECODED IDENTIFIER DATA <<", width / 2, textY);

                barcodes.forEach((barcode) => {
                    textY += (width * 0.025);
                    ctx.fillText(`[${barcode.format}]: ${barcode.rawValue}`, width / 2, textY);

                    // Map red bounding box over the real detected barcode/QR
                    ctx.strokeStyle = "rgba(255, 0, 0, 0.8)";
                    ctx.lineWidth = Math.max(2, width * 0.005);
                    ctx.strokeRect(barcode.boundingBox.x, barcode.boundingBox.y, barcode.boundingBox.width, barcode.boundingBox.height);
                });
            } else {
                ctx.font = `${Math.max(12, width * 0.018)}px "Courier New", Courier, monospace`;
                ctx.fillText("AWAITING ID DATA...", width / 2, idY + idHeight + (height * 0.03));
            }
        } else {
            // Fallback GUI text if API is unavailable
            ctx.textAlign = 'center';
            ctx.textBaseline = 'top';
            ctx.font = `${Math.max(12, width * 0.018)}px "Courier New", Courier, monospace`;
            ctx.fillText("AWAITING ID DATA...", width / 2, idY + idHeight + (height * 0.03));
        }
    } catch (err) {
        console.log("Barcode detection encountered an error: ", err);
    }

    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 you to apply a high-tech scanner overlay to your images, simulating an ID scanning or biometric verification process. It creates a focused viewing area for identification cards, complete with digital reticles, a laser scan line, and camcorder-style UI elements like recording indicators and timestamps. The tool can also attempt to detect and display decoded barcode or QR code information directly on the image. It is ideal for creating cinematic visual effects, UI mockups for security applications, or stylized graphics for presentations and digital content.

Leave a Reply

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