Please bookmark this page to avoid losing your image tool!

Photo Face Mask Adder

(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, maskType = 'medical', maskColor = '#00a8cc', maskScale = '1.0') {
    const scale = parseFloat(maskScale) || 1.0;
    const validMaskType = maskType.toLowerCase() === 'masquerade' ? 'masquerade' : 'medical';

    const canvas = document.createElement('canvas');
    canvas.width = originalImg.width || originalImg.naturalWidth;
    canvas.height = originalImg.height || originalImg.naturalHeight;
    const ctx = canvas.getContext('2d');
    
    // Draw the original image onto the canvas
    ctx.drawImage(originalImg, 0, 0, canvas.width, canvas.height);

    // Dynamically load face-api.js if it isn't already available
    if (typeof window.faceapi === 'undefined') {
        if (!window.faceapiLoadingPromise) {
            window.faceapiLoadingPromise = new Promise((resolve, reject) => {
                const script = document.createElement('script');
                script.src = 'https://cdn.jsdelivr.net/npm/@vladmandic/face-api/dist/face-api.min.js';
                script.onload = resolve;
                script.onerror = () => reject(new Error('Failed to load Face-API.js library'));
                document.head.appendChild(script);
            });
        }
        try {
            await window.faceapiLoadingPromise;
        } catch (err) {
            console.error(err);
        }
    }

    let boxes = [];
    if (typeof window.faceapi !== 'undefined') {
        try {
            // Load the face detection model
            if (!window.faceapiModelLoaded) {
                const modelPath = 'https://cdn.jsdelivr.net/npm/@vladmandic/face-api/model/';
                await window.faceapi.nets.tinyFaceDetector.loadFromUri(modelPath);
                window.faceapiModelLoaded = true;
            }
            
            // Detect all faces in the canvas
            const detections = await window.faceapi.detectAllFaces(
                canvas, 
                new window.faceapi.TinyFaceDetectorOptions()
            );
            
            if (detections && detections.length > 0) {
                boxes = detections.map(d => d.box);
            }
        } catch (err) {
            console.error('Face detection failed, using fallback placement.', err);
        }
    }

    // If no face found or API failed, place a default mask in the center
    if (boxes.length === 0) {
        boxes.push({
            x: canvas.width * 0.35,
            y: canvas.height * 0.35,
            width: canvas.width * 0.3,
            height: canvas.width * 0.3
        });
    }

    // Helper function to draw rectangles with border radius
    const roundRect = (ctx, x, y, w, h, r) => {
        if (w < 2 * r) r = w / 2;
        if (h < 2 * r) r = h / 2;
        ctx.beginPath();
        ctx.moveTo(x + r, y);
        ctx.arcTo(x + w, y, x + w, y + h, r);
        ctx.arcTo(x + w, y + h, x, y + h, r);
        ctx.arcTo(x, y + h, x, y, r);
        ctx.arcTo(x, y, x + w, y, r);
        ctx.closePath();
    };

    // Helper to draw the specified mask based on face dimensions
    const drawMask = (box) => {
        ctx.save();
        const centerX = box.x + box.width / 2;
        let w, h, x, y;

        if (validMaskType === 'masquerade') {
            w = box.width * 1.2 * scale;
            h = box.height * 0.45 * scale;
            x = centerX - w / 2;
            y = box.y + box.height * 0.15;

            // Offscreen canvas for hole punching the eyes
            const mCanv = document.createElement('canvas');
            mCanv.width = w;
            mCanv.height = h;
            const mCtx = mCanv.getContext('2d');
            mCtx.translate(w / 2, h / 2);

            // Shape of the domino masquerade mask
            mCtx.fillStyle = maskColor || '#000000';
            mCtx.beginPath();
            mCtx.moveTo(0, -h * 0.3); 
            mCtx.quadraticCurveTo(w * 0.3, -h * 0.6, w * 0.5, -h * 0.2);
            mCtx.quadraticCurveTo(w * 0.5, h * 0.4, w * 0.3, h * 0.5); 
            mCtx.quadraticCurveTo(w * 0.15, h * 0.4, 0, h * 0.1); 
            mCtx.quadraticCurveTo(-w * 0.15, h * 0.4, -w * 0.3, h * 0.5); 
            mCtx.quadraticCurveTo(-w * 0.5, h * 0.4, -w * 0.5, -h * 0.2); 
            mCtx.quadraticCurveTo(-w * 0.3, -h * 0.6, 0, -h * 0.3);
            mCtx.fill();

            // Punch the eye holes
            mCtx.globalCompositeOperation = 'destination-out';
            mCtx.fillStyle = '#ffffff';
            mCtx.beginPath(); // Right eye
            mCtx.ellipse(w * 0.22, 0, w * 0.08, h * 0.12, 0.1, 0, Math.PI * 2);
            mCtx.fill();
            mCtx.beginPath(); // Left eye
            mCtx.ellipse(-w * 0.22, 0, w * 0.08, h * 0.12, -0.1, 0, Math.PI * 2);
            mCtx.fill();

            ctx.drawImage(mCanv, x, y);

            // Draw masquerade ties
            ctx.strokeStyle = 'rgba(0,0,0,0.6)';
            ctx.lineWidth = 1.5;
            ctx.beginPath();
            ctx.moveTo(x, y + h / 2);
            ctx.lineTo(box.x - box.width * 0.1, box.y + box.height * 0.25);
            ctx.moveTo(x + w, y + h / 2);
            ctx.lineTo(box.x + box.width * 1.1, box.y + box.height * 0.25);
            ctx.stroke();

        } else { // Medical Mask
            w = box.width * 1.05 * scale;
            h = box.height * 0.55 * scale;
            x = centerX - w / 2;
            y = box.y + box.height * 0.45;

            // Draw elastic ear loops
            ctx.strokeStyle = '#ffffff';
            ctx.lineWidth = 2.5 * scale;
            ctx.beginPath();
            // Left loop
            ctx.moveTo(x + w * 0.05, y + h * 0.15);
            ctx.quadraticCurveTo(box.x - box.width * 0.2, y + h * 0.5, x + w * 0.05, y + h * 0.85);
            // Right loop
            ctx.moveTo(x + w * 0.95, y + h * 0.15);
            ctx.quadraticCurveTo(box.x + box.width * 1.2, y + h * 0.5, x + w * 0.95, y + h * 0.85);
            ctx.stroke();

            // Mask body
            ctx.fillStyle = maskColor || '#a3e4d7'; // Default medical cyan
            
            roundRect(ctx, x, y, w, h, 10 * scale);
            ctx.fill();

            // Medical pleats/folds texture
            ctx.strokeStyle = 'rgba(255, 255, 255, 0.5)';
            ctx.lineWidth = 1.5 * scale;
            ctx.beginPath();
            ctx.moveTo(x + w * 0.05, y + h * 0.33);
            ctx.lineTo(x + w * 0.95, y + h * 0.33);
            ctx.moveTo(x + w * 0.05, y + h * 0.66);
            ctx.lineTo(x + w * 0.95, y + h * 0.66);
            ctx.stroke();

            // Adjustable nose wire
            ctx.strokeStyle = 'rgba(255, 255, 255, 0.8)';
            ctx.lineWidth = 3 * scale;
            ctx.beginPath();
            ctx.moveTo(x + w * 0.35, y + 2 * scale);
            ctx.lineTo(x + w * 0.65, y + 2 * scale);
            ctx.stroke();
        }

        ctx.restore();
    };

    // Apply masks to all detected faces
    for (const box of boxes) {
        drawMask(box);
    }

    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 Photo Face Mask Adder is an image editing tool that uses face detection technology to automatically add digital masks to people in photos. Users can choose between different styles, such as medical masks or masquerade masks, and customize the appearance with adjustable colors and scaling. This tool is useful for creating themed social media content, generating humorous images, or adding medical-style overlays for specific visual contexts.

Leave a Reply

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

Other Image Tools:

YouTube Video To Image Frame Extractor

Image Translation and Language Tool

TV Logo Compilation Image Creator

Image Food Delivery Service Tool

Image To Target Language Dubbing Text Translator

Image Search Tools

Image and Video Player

Image Flip and Reverse Tool

Three Photo Mediateka

Image Description Identifier Tool

Two Photo Comparison Search Tool

Image Name Official Tool

Video Audio Track Language Dubbing Translator Tool

Multi Language HiFi VHSRip and DVDRip Audio Player

Image To Stylized Character Hero Generator

AI Image Idea Generator

Image Topic Search and Mediateka Creator Tool

Image Based Advanced Movie Identifier Search Tool

Image Movie Identifier Advanced Search Tool

Image Aspect Ratio Calculator By Numbers

SEO Topic Search Image Finder Tool

VHSRip and DVDRip Audio Track and Language Translator Tool

Video Audio Track and Language Dub Text Translator Downloader

HIFI VHSRip Mono Effects Image Applier

Image To Online Website Address Converter

YouTube Video Title Renamer Based on URL Tool

Image URL Web Interface Tool

Movie Languages and Auto Dubbing Translation Tool

Video Platform Metadata and DVDRip Text Downloader Tool

YouTube Video Multilingual Auto Dubbing Tool

Video Platform Language Dubbing Text Downloader and Translator Tool

HIFI VHSRip Video Metadata and Subtitle Downloader

Video and Audio Metadata Text Extractor Tool

Search and Download TV Video Platform Audio Dubbing Text Translator

Video Platform Audio Track and Language Dubbing Text Downloader

Video Platform Audio Track Language Dub Translator and Downloader

See All →