Please bookmark this page to avoid losing your image tool!

Website Icon And Favicon Screenshot Identifier Scanner

(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, domain = 'example.com', title = 'Home - My Website', favicon = '🌐', theme = 'light', bg = 'gradient') {
    return new Promise(async (resolve, reject) => {
        try {
            const canvas = document.createElement('canvas');
            const ctx = canvas.getContext('2d');
            
            // Validate and size image
            if (!originalImg || !originalImg.width) {
                throw new Error("Invalid or unloaded image provided.");
            }

            const minW = 480;
            let width = originalImg.width;
            let height = originalImg.height;
            
            // Proportional scale up if below min-width
            if (width < minW) {
                const ratio = minW / width;
                width = minW;
                height = height * ratio;
            }
            
            // Dynamic scale factor for UI
            const s = Math.max(0.6, width / 1200);
            
            // UI Proportions
            const padding = 40 * s;
            const tabAreaH = 40 * s;
            const navAreaH = 40 * s;
            const headerH = tabAreaH + navAreaH;
            const r = 10 * s;
            
            canvas.width = width + padding * 2;
            canvas.height = height + headerH + padding * 2;
            
            // Reusable logic for drawing rounded rectangles
            const drawRoundRect = (ctx, x, y, w, h, radii) => {
                let tl = 0, tr = 0, br = 0, bl = 0;
                if (typeof radii === 'number') { tl = tr = br = bl = radii; }
                else if (Array.isArray(radii)) {
                    if (radii.length === 4) { [tl, tr, br, bl] = radii; }
                    else if (radii.length === 2) { [tl, tr] = radii; br = tl; bl = tr; }
                }
                ctx.beginPath();
                ctx.moveTo(x + tl, y);
                ctx.lineTo(x + w - tr, y);
                ctx.quadraticCurveTo(x + w, y, x + w, y + tr);
                ctx.lineTo(x + w, y + h - br);
                ctx.quadraticCurveTo(x + w, y + h, x + w - br, y + h);
                ctx.lineTo(x + bl, y + h);
                ctx.quadraticCurveTo(x, y + h, x, y + h - bl);
                ctx.lineTo(x, y + tl);
                ctx.quadraticCurveTo(x, y, x + tl, y);
                ctx.closePath();
            };
            
            // 1. Draw Canvas Background
            if (bg.toLowerCase() === 'gradient') {
                const grad = ctx.createLinearGradient(0, 0, canvas.width, canvas.height);
                grad.addColorStop(0, '#e2e8f0');
                grad.addColorStop(1, '#94a3b8');
                ctx.fillStyle = grad;
            } else {
                ctx.fillStyle = bg;
            }
            ctx.fillRect(0, 0, canvas.width, canvas.height);
            
            // Window Base Settings
            const wX = padding;
            const wY = padding;
            const wW = width;
            const wH = height + headerH;
            
            const isDark = theme.toLowerCase() === 'dark';
            const frameColor = isDark ? '#202124' : '#dee1e6';
            const tabBg = isDark ? '#35363a' : '#ffffff';
            const textColor = isDark ? '#f1f3f4' : '#3c4043';
            const mutedText = isDark ? '#9aa0a6' : '#5f6368';
            
            // 2. Draw Window Shadow and Base Frame 
            ctx.shadowColor = 'rgba(0, 0, 0, 0.3)';
            ctx.shadowBlur = 25 * s;
            ctx.shadowOffsetY = 15 * s;
            
            ctx.fillStyle = frameColor;
            drawRoundRect(ctx, wX, wY, wW, wH, r);
            ctx.fill();
            
            ctx.shadowColor = 'transparent'; // Stop shadow for subsequent inner drawings
            
            // 3. Draw Tab Header Content (Mac Style Dots)
            const dotY = wY + tabAreaH / 2;
            const dotR = 6 * s;
            const dotGap = 20 * s;
            ['#ff5f56', '#ffbd2e', '#27c93f'].forEach((color, i) => {
                ctx.beginPath();
                ctx.arc(wX + 20 * s + i * dotGap, dotY, dotR, 0, Math.PI * 2);
                ctx.fillStyle = color;
                ctx.fill();
            });
            
            // 4. Draw Active Tab
            const tabX = wX + 80 * s;
            const tabY = wY + 8 * s;
            const tabW = Math.min(240 * s, wW - tabX - 10 * s); // responsive tab width
            const tabH = tabAreaH - 8 * s;
            const tabR = 8 * s;
            
            ctx.fillStyle = tabBg;
            drawRoundRect(ctx, tabX, tabY, tabW, tabH, [tabR, tabR, 0, 0]);
            ctx.fill();
            
            // Add Favicon
            const textY = tabY + tabH / 2;
            const favSize = 16 * s;
            const titleOffset = 35 * s;
            
            if (favicon.startsWith('data:image/')) {
                const imgParams = new Image();
                await new Promise(res => {
                    imgParams.onload = () => {
                        ctx.drawImage(imgParams, tabX + 12 * s, textY - favSize / 2, favSize, favSize);
                        res();
                    };
                    imgParams.onerror = () => res(); // fail gracefully
                    imgParams.src = favicon;
                });
            } else {
                ctx.font = `${14 * s}px sans-serif`;
                ctx.textBaseline = 'middle';
                ctx.fillStyle = textColor;
                ctx.fillText(favicon, tabX + 12 * s, textY);
            }
            
            // Add Tab Title
            ctx.fillStyle = textColor;
            ctx.font = `${12 * s}px sans-serif`;
            
            let dispTitle = title;
            const maxTitleW = tabW - titleOffset - 15 * s;
            while(ctx.measureText(dispTitle).width > maxTitleW && dispTitle.length > 0) {
                dispTitle = dispTitle.slice(0, -2) + '…';
            }
            ctx.fillText(dispTitle, tabX + titleOffset, textY);
            
            // 5. Draw Navigation Bar Background
            ctx.fillStyle = tabBg;
            ctx.fillRect(wX, wY + tabAreaH, wW, navAreaH);
            
            ctx.beginPath();
            ctx.moveTo(wX, wY + headerH);
            ctx.lineTo(wX + wW, wY + headerH);
            ctx.strokeStyle = isDark ? '#000000' : '#dadce0';
            ctx.lineWidth = 1;
            ctx.stroke();
            
            // 6. Draw Navigation Icons
            ctx.fillStyle = mutedText;
            ctx.font = `${16 * s}px sans-serif`;
            const navYCenter = wY + tabAreaH + navAreaH / 2;
            ctx.fillText('←', wX + 20 * s, navYCenter);
            ctx.fillText('→', wX + 50 * s, navYCenter);
            ctx.fillText('↻', wX + 80 * s, navYCenter);
            
            // 7. Draw Address Bar Pill
            const addrX = wX + 110 * s;
            const addrY = wY + tabAreaH + 6 * s;
            const addrW = wW - addrX - 20 * s;
            const addrH = navAreaH - 12 * s;
            
            ctx.fillStyle = isDark ? '#202124' : '#f1f3f4';
            drawRoundRect(ctx, addrX, addrY, addrW, addrH, addrH / 2);
            ctx.fill();
            
            // 8. Draw Lock and URL text
            ctx.fillStyle = mutedText;
            ctx.font = `${11 * s}px sans-serif`;
            ctx.fillText('🔒', addrX + 15 * s, navYCenter);
            
            const cleanDomain = domain.replace(/^https?:\/\//, '');
            ctx.fillStyle = textColor;
            ctx.font = `${14 * s}px sans-serif`;
            
            ctx.save();
            ctx.beginPath();
            ctx.rect(addrX + 35 * s, addrY, addrW - 40 * s, addrH);
            ctx.clip(); // Ensure URL doesn't spill out of address bar
            ctx.fillText(`https://${cleanDomain}`, addrX + 40 * s, navYCenter);
            ctx.restore();
            
            // 9. Draw the internal Screenshot image
            ctx.save();
            ctx.beginPath();
            drawRoundRect(ctx, wX, wY + headerH, wW, height, [0, 0, r, r]);
            ctx.clip();
            ctx.drawImage(originalImg, wX, wY + headerH, width, height);
            ctx.restore();
            
            // Resolve standard promise with canvas
            resolve(canvas);
        } catch (err) {
            reject(err);
        }
    });
}

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 transforms a standard website screenshot into a stylized browser window mockup. It overlays the provided image with a realistic browser interface, including a tab bar featuring a customizable favicon and page title, a navigation bar with back/forward/refresh icons, and a URL address bar. Users can customize the appearance by selecting different themes (light or dark) and background gradients. This tool is ideal for web designers, developers, and marketers who want to create professional, high-quality presentations of their websites for portfolios, social media, or client demonstrations.

Leave a Reply

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