Please bookmark this page to avoid losing your image tool!

Image To CCTV Camera Footage Converter

(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, timestamp = '', camId = 'CAM 01', showRec = 1, noiseAmount = 0.1, scanlineOpacity = 0.1, vignetteAmount = 0.5, saturation = 0) {
    // 1. Setup Canvas
    const canvas = document.createElement('canvas');
    const ctx = canvas.getContext('2d');
    const {
        width,
        height
    } = originalImg;
    canvas.width = width;
    canvas.height = height;

    // 2. Dynamically load a monospaced font for the overlay text.
    // This is async, so the function must be async.
    try {
        const font = new FontFace('CCTVFont', 'url(https://fonts.gstatic.com/s/robotomono/v22/L0x5DF4xlVMF-BfR8bXMIjhGq3-cXbKDO1w.woff2)');
        await font.load();
        document.fonts.add(font);
    } catch (e) {
        console.error("CCTV font could not be loaded. A default monospace font will be used.", e);
    }

    // 3. Draw the base image with color saturation adjustment.
    // saturation=0 creates a grayscale image.
    ctx.filter = `saturate(${saturation})`;
    ctx.drawImage(originalImg, 0, 0, width, height);
    ctx.filter = 'none'; // Reset filter for subsequent drawings

    // 4. Add noise to the image.
    if (noiseAmount > 0) {
        const imageData = ctx.getImageData(0, 0, width, height);
        const data = imageData.data;
        const noiseFactor = 255 * Math.max(0, Math.min(1, noiseAmount));
        for (let i = 0; i < data.length; i += 4) {
            // Add the same random noise to R, G, and B channels
            const noise = (Math.random() - 0.5) * noiseFactor;
            data[i] = Math.max(0, Math.min(255, data[i] + noise));
            data[i + 1] = Math.max(0, Math.min(255, data[i + 1] + noise));
            data[i + 2] = Math.max(0, Math.min(255, data[i + 2] + noise));
        }
        ctx.putImageData(imageData, 0, 0);
    }

    // 5. Add horizontal scan lines.
    if (scanlineOpacity > 0) {
        ctx.fillStyle = `rgba(0, 0, 0, ${scanlineOpacity})`;
        for (let i = 0; i < height; i += 3) {
            ctx.fillRect(0, i, width, 1);
        }
    }

    // 6. Add a vignette effect (darker corners).
    if (vignetteAmount > 0) {
        const outerRadius = Math.sqrt(Math.pow(width / 2, 2) + Math.pow(height / 2, 2));
        const gradient = ctx.createRadialGradient(
            width / 2, height / 2, outerRadius * (1 - vignetteAmount),
            width / 2, height / 2, outerRadius
        );
        gradient.addColorStop(0, 'rgba(0,0,0,0)');
        // A darker, more opaque black at the very edge.
        gradient.addColorStop(1, 'rgba(0,0,0,0.8)');
        ctx.fillStyle = gradient;
        ctx.fillRect(0, 0, width, height);
    }

    // 7. Add text overlays (CAM ID, REC, Timestamp).
    const fontSize = Math.max(12, Math.round(height / 35));
    const padding = fontSize * 0.5;
    ctx.font = `${fontSize}px CCTVFont, monospace`;
    ctx.fillStyle = 'rgba(255, 255, 255, 0.75)';
    ctx.textBaseline = 'top';

    // Top-left: Camera ID
    if (camId) {
        ctx.textAlign = 'left';
        ctx.fillText(camId, padding, padding);
    }

    // Top-right: REC indicator
    if (Number(showRec) === 1) {
        ctx.textAlign = 'right';
        const recText = "REC";
        const textMetrics = ctx.measureText(recText);
        const recTextX = width - padding;
        const recTextY = padding;

        ctx.fillStyle = 'rgba(255, 255, 255, 0.75)';
        ctx.fillText(recText, recTextX, recTextY);

        const recCircleRadius = fontSize / 3;
        // Position circle to the left of the "REC" text
        const circleX = recTextX - textMetrics.width - recCircleRadius - (padding / 2);
        const circleY = recTextY + (fontSize / 2);

        ctx.fillStyle = 'rgba(255, 0, 0, 0.9)';
        ctx.beginPath();
        ctx.arc(circleX, circleY, recCircleRadius, 0, 2 * Math.PI);
        ctx.fill();
    }

    // Bottom-right: Timestamp
    let ts = timestamp;
    if (!ts) {
        const now = new Date();
        const YYYY = now.getFullYear();
        const MM = String(now.getMonth() + 1).padStart(2, '0');
        const DD = String(now.getDate()).padStart(2, '0');
        const hh = String(now.getHours()).padStart(2, '0');
        const mm = String(now.getMinutes()).padStart(2, '0');
        const ss = String(now.getSeconds()).padStart(2, '0');
        ts = `${YYYY}-${MM}-${DD} ${hh}:${mm}:${ss}`;
    }

    if (ts) {
        ctx.textAlign = 'right';
        ctx.textBaseline = 'bottom';
        ctx.fillStyle = 'rgba(255, 255, 255, 0.75)';
        ctx.fillText(ts, width - padding, height - padding);
    }

    // 8. Return the final canvas.
    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 To CCTV Camera Footage Converter is a tool designed to transform standard images into a stylized representation reminiscent of CCTV camera footage. This tool can be used to enhance images by applying various effects such as noise, scan lines, and a vignette effect, making the image appear more like it was captured by a surveillance camera. Additionally, users can overlay contextual information such as camera ID, recording indicators, and timestamps on the images. This can be beneficial for creating mock surveillance footage, artistic images, or for use in security-related presentations and content.

Leave a Reply

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