Please bookmark this page to avoid losing your image tool!

Quick Photo Capture 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.
function processImage(originalImg, themeColor = '#007bff') {
    // Create main container
    const container = document.createElement('div');
    container.style.display = 'flex';
    container.style.flexDirection = 'column';
    container.style.alignItems = 'center';
    container.style.gap = '15px';
    container.style.fontFamily = 'system-ui, -apple-system, sans-serif';
    container.style.position = 'relative';
    container.style.width = '100%';
    container.style.maxWidth = '800px';
    container.style.margin = '0 auto';
    container.style.padding = '20px';
    container.style.backgroundColor = '#2c2c2c';
    container.style.borderRadius = '12px';
    container.style.boxShadow = '0 8px 16px rgba(0,0,0,0.3)';
    container.style.boxSizing = 'border-box';

    // Create the display view area for the camera preview / taken photo
    const viewArea = document.createElement('div');
    viewArea.style.position = 'relative';
    viewArea.style.width = '100%';
    viewArea.style.display = 'flex';
    viewArea.style.justifyContent = 'center';
    viewArea.style.alignItems = 'center';
    viewArea.style.overflow = 'hidden';
    viewArea.style.borderRadius = '8px';
    viewArea.style.backgroundColor = '#000';
    viewArea.style.minHeight = '300px';

    const video = document.createElement('video');
    video.autoplay = true;
    video.playsInline = true;
    video.style.maxWidth = '100%';
    video.style.maxHeight = '60vh';
    video.style.objectFit = 'contain';

    const canvas = document.createElement('canvas');
    canvas.style.display = 'none';
    canvas.style.maxWidth = '100%';
    canvas.style.maxHeight = '60vh';
    canvas.style.objectFit = 'contain';

    viewArea.appendChild(video);
    viewArea.appendChild(canvas);
    
    // Aesthetic Viewfinder overlay targeting the center
    const viewfinder = document.createElement('div');
    viewfinder.style.position = 'absolute';
    viewfinder.style.top = '50%';
    viewfinder.style.left = '50%';
    viewfinder.style.transform = 'translate(-50%, -50%)';
    viewfinder.style.width = '50%';
    viewfinder.style.height = '50%';
    viewfinder.style.pointerEvents = 'none';
    
    const bracketStyle = 'position: absolute; width: 30px; height: 30px; border-color: rgba(255,255,255,0.7); border-style: solid;';
    viewfinder.innerHTML = `
        <div style="${bracketStyle} top: 0; left: 0; border-width: 4px 0 0 4px;"></div>
        <div style="${bracketStyle} top: 0; right: 0; border-width: 4px 4px 0 0;"></div>
        <div style="${bracketStyle} bottom: 0; left: 0; border-width: 0 0 4px 4px;"></div>
        <div style="${bracketStyle} bottom: 0; right: 0; border-width: 0 4px 4px 0;"></div>
        <div style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 6px; height: 6px; border-radius: 50%; background: rgba(255,0,0,0.7);"></div>
    `;
    viewArea.appendChild(viewfinder);

    // Flash effect element for "Щёлк!" feedback
    const flash = document.createElement('div');
    flash.style.position = 'absolute';
    flash.style.top = '0';
    flash.style.left = '0';
    flash.style.width = '100%';
    flash.style.height = '100%';
    flash.style.backgroundColor = '#fff';
    flash.style.opacity = '0';
    flash.style.pointerEvents = 'none';
    flash.style.transition = 'opacity 0.2s ease-out';
    viewArea.appendChild(flash);

    // Buttons Container
    const controls = document.createElement('div');
    controls.style.display = 'flex';
    controls.style.gap = '15px';
    controls.style.flexWrap = 'wrap';
    controls.style.justifyContent = 'center';
    controls.style.marginTop = '10px';

    const createBtn = (text, bgColor) => {
        const btn = document.createElement('button');
        btn.innerHTML = text;
        btn.style.padding = '12px 24px';
        btn.style.fontSize = '16px';
        btn.style.fontWeight = 'bold';
        btn.style.cursor = 'pointer';
        btn.style.border = 'none';
        btn.style.borderRadius = '30px';
        btn.style.backgroundColor = bgColor;
        btn.style.color = '#fff';
        btn.style.transition = 'transform 0.1s, opacity 0.2s';
        btn.onmousedown = () => btn.style.transform = 'scale(0.95)';
        btn.onmouseup = () => btn.style.transform = 'scale(1)';
        btn.onmouseover = () => btn.style.opacity = '0.9';
        btn.onmouseout = () => btn.style.opacity = '1';
        return btn;
    };

    const captureBtn = createBtn('📸 Capture', themeColor);
    const retryBtn = createBtn('🔄 Retake', '#6c757d');
    const dlBtn = createBtn('💾 Save Photo', '#28a745');

    retryBtn.style.display = 'none';
    dlBtn.style.display = 'none';

    controls.appendChild(captureBtn);
    controls.appendChild(retryBtn);
    controls.appendChild(dlBtn);

    container.appendChild(viewArea);
    container.appendChild(controls);

    let stream = null;
    let fallbackMode = false;

    // Start Webcam or Fallback to Original Image
    async function startCamera() {
        try {
            if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
                stream = await navigator.mediaDevices.getUserMedia({ video: { facingMode: 'user' }, audio: false });
                video.srcObject = stream;
                fallbackMode = false;
            } else {
                throw new Error("getUserMedia not supported");
            }
        } catch (err) {
            console.warn("Camera access denied/unavailable. Implementing fallback mechanism using originalImg.");
            fallbackMode = true;
            video.style.display = 'none';
            canvas.style.display = 'block';
            
            canvas.width = originalImg.naturalWidth || originalImg.width || 800;
            canvas.height = originalImg.naturalHeight || originalImg.height || 600;
            const ctx = canvas.getContext('2d');
            
            if (canvas.width > 0 && canvas.height > 0) {
                ctx.drawImage(originalImg, 0, 0, canvas.width, canvas.height);
            } else {
                ctx.fillStyle = '#444';
                ctx.fillRect(0, 0, canvas.width, canvas.height);
                ctx.fillStyle = '#fff';
                ctx.font = '24px sans-serif';
                ctx.textAlign = 'center';
                ctx.fillText('Camera unavailable & No Image Provided', canvas.width / 2, canvas.height / 2);
            }
        }
    }

    startCamera();

    // Listeners for functionality
    captureBtn.addEventListener('click', () => {
        // Shutter flash effect
        flash.style.opacity = '1';
        setTimeout(() => flash.style.opacity = '0', 150);

        viewfinder.style.display = 'none';

        if (!fallbackMode) {
            const w = video.videoWidth || 640;
            const h = video.videoHeight || 480;
            canvas.width = w;
            canvas.height = h;
            const ctx = canvas.getContext('2d');
            ctx.drawImage(video, 0, 0, w, h);

            video.style.display = 'none';
            canvas.style.display = 'block';
        }

        captureBtn.style.display = 'none';
        retryBtn.style.display = 'block';
        dlBtn.style.display = 'block';
    });

    retryBtn.addEventListener('click', () => {
        viewfinder.style.display = 'block';
        if (!fallbackMode) {
            video.style.display = 'block';
            canvas.style.display = 'none';
        }
        captureBtn.style.display = 'block';
        retryBtn.style.display = 'none';
        dlBtn.style.display = 'none';
    });

    dlBtn.addEventListener('click', () => {
        const link = document.createElement('a');
        link.download = `photo_capture_${Date.now()}.png`;
        link.href = canvas.toDataURL('image/png', 1.0);
        link.click();
    });

    // Cleanup tracks safely when element is removed from DOM to prevent webcam staying active
    let wasInDOM = false;
    const observer = new MutationObserver(() => {
        const inDOM = document.body.contains(container);
        if (inDOM) {
            wasInDOM = true;
        } else if (wasInDOM && !inDOM) {
            if (stream) {
                stream.getTracks().forEach(track => track.stop());
            }
            observer.disconnect();
        }
    });
    observer.observe(document.body, { childList: true, subtree: true });

    return container;
}

Free Image Tool Creator

Can't find the image tool you're looking for?
Create one based on your own needs now!

Description

The Quick Photo Capture Tool provides a web-based interface for capturing instant photographs using your device’s webcam. It features an interactive viewfinder, a shutter flash effect for real-time feedback, and options to retake or save your captured images directly to your device. This tool is useful for quickly taking selfies, capturing product photos, or generating instant snapshots for documentation and social media.

Leave a Reply

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