Please bookmark this page to avoid losing your image tool!

Television Icon Image Generator

(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, tvColor = '#d28c46', panelColor = '#222222', enableCRT = 1) {
    const drawRoundRect = (ctx, x, y, width, height, radius) => {
        ctx.beginPath();
        ctx.moveTo(x + radius, y);
        ctx.lineTo(x + width - radius, y);
        ctx.quadraticCurveTo(x + width, y, x + width, y + radius);
        ctx.lineTo(x + width, y + height - radius);
        ctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height);
        ctx.lineTo(x + radius, y + height);
        ctx.quadraticCurveTo(x, y + height, x, y + height - radius);
        ctx.lineTo(x, y + radius);
        ctx.quadraticCurveTo(x, y, x + radius, y);
        ctx.closePath();
    };

    const W = originalImg.width;
    const H = originalImg.height;

    // Scale down if image is too large to keep canvas manageable visually
    const maxDim = 700;
    let scale = 1;
    if (W > maxDim || H > maxDim) {
        scale = maxDim / Math.max(W, H);
    }

    const sw = W * scale;
    const sh = H * scale;

    // Dynamic metrics based on screen size
    const margin = Math.max(sw * 0.08, 20);
    const panelW = Math.max(sw * 0.25, 60);

    const tvW = sw + panelW + margin * 3;
    const tvH = sh + margin * 2;

    const antH = Math.max(sh * 0.25, 40);
    const legH = Math.max(sh * 0.15, 30);

    const padCanvas = 40;
    const canvas = document.createElement('canvas');
    canvas.width = tvW + padCanvas * 2;
    canvas.height = tvH + antH + legH + padCanvas * 2;
    const ctx = canvas.getContext('2d');

    const startX = padCanvas;
    const startY = padCanvas + antH;

    // --- Draw TV Legs ---
    ctx.fillStyle = tvColor;
    ctx.strokeStyle = '#333';
    ctx.lineWidth = 3;
    const legW = margin * 0.8;
    
    // Left Leg
    ctx.beginPath();
    const llX = startX + tvW * 0.15;
    const llY = startY + tvH - 10;
    ctx.moveTo(llX - legW/2, llY);
    ctx.lineTo(llX + legW/2, llY);
    ctx.lineTo(llX + legW, llY + legH);
    ctx.lineTo(llX - legW*0.2, llY + legH);
    ctx.closePath();
    ctx.fill(); ctx.stroke();

    // Right Leg
    ctx.beginPath();
    const rlX = startX + tvW * 0.85;
    ctx.moveTo(rlX - legW/2, llY);
    ctx.lineTo(rlX + legW/2, llY);
    ctx.lineTo(rlX + legW*0.2, llY + legH);
    ctx.lineTo(rlX - legW, llY + legH);
    ctx.closePath();
    ctx.fill(); ctx.stroke();

    // --- Draw Antenna ---
    const antBaseX = startX + tvW / 2;
    ctx.lineWidth = 4;
    ctx.strokeStyle = '#999';
    ctx.beginPath();
    ctx.moveTo(antBaseX, startY);
    ctx.lineTo(antBaseX - tvW * 0.25, startY - antH);
    ctx.moveTo(antBaseX, startY);
    ctx.lineTo(antBaseX + tvW * 0.25, startY - antH);
    ctx.stroke();

    // Antenna Tips
    ctx.fillStyle = '#555';
    ctx.beginPath();
    ctx.arc(antBaseX - tvW * 0.25, startY - antH, 6, 0, Math.PI * 2);
    ctx.fill();
    ctx.beginPath();
    ctx.arc(antBaseX + tvW * 0.25, startY - antH, 6, 0, Math.PI * 2);
    ctx.fill();

    // Antenna Base
    ctx.fillStyle = '#222';
    drawRoundRect(ctx, antBaseX - 30, startY - 8, 60, 16, 4);
    ctx.fill();

    // --- Draw TV Body ---
    ctx.shadowColor = 'rgba(0,0,0,0.4)';
    ctx.shadowBlur = 20;
    ctx.shadowOffsetX = 5;
    ctx.shadowOffsetY = 10;
    
    ctx.fillStyle = tvColor;
    drawRoundRect(ctx, startX, startY, tvW, tvH, margin * 0.5);
    ctx.fill();

    // Reset shadow
    ctx.shadowColor = 'transparent';
    ctx.shadowBlur = 0;
    ctx.shadowOffsetX = 0;
    ctx.shadowOffsetY = 0;

    // Body Outline
    ctx.lineWidth = 4;
    ctx.strokeStyle = '#222';
    ctx.stroke();

    // --- Draw Hardware Panel ---
    const pX = startX + margin * 2 + sw;
    const pY = startY + margin;
    ctx.fillStyle = panelColor;
    drawRoundRect(ctx, pX, pY, panelW, sh, margin * 0.2);
    ctx.fill();

    // Panel Dials / Knobs
    const dialR = Math.min(panelW * 0.35, sh * 0.15);
    const dialX = pX + panelW / 2;
    let dialY1 = pY + margin + dialR;
    let dialY2 = dialY1 + dialR * 2.5;

    const drawDial = (x, y) => {
        // Outer shiny ring
        ctx.fillStyle = '#6a6a6a';
        ctx.beginPath(); ctx.arc(x, y, dialR, 0, Math.PI * 2); ctx.fill();
        // Inner knob base
        ctx.fillStyle = '#e0e0e0';
        ctx.beginPath(); ctx.arc(x, y, dialR * 0.75, 0, Math.PI * 2); ctx.fill();
        // Knob shadow/depth rim
        ctx.strokeStyle = '#999'; ctx.lineWidth = 2; ctx.stroke();
        // Positional notch mark
        ctx.strokeStyle = '#222';
        ctx.lineWidth = 4;
        ctx.lineCap = 'round';
        ctx.beginPath();
        ctx.moveTo(x, y);
        const angle = -Math.PI / 4 + (Math.random() * Math.PI); // Randomize dial twist
        ctx.lineTo(x + Math.cos(angle) * dialR * 0.6, y + Math.sin(angle) * dialR * 0.6);
        ctx.stroke();
    };

    drawDial(dialX, dialY1);
    drawDial(dialX, dialY2);

    // Speaker Grill
    const grillY = dialY2 + dialR * 1.5;
    const grillH = sh - (grillY - pY) - margin;
    if (grillH > 15) {
        ctx.fillStyle = '#111';
        const slots = Math.max(3, Math.floor(grillH / 14));
        const slotSpacing = grillH / slots;
        for (let i = 0; i < slots; i++) {
            drawRoundRect(ctx, pX + panelW * 0.2, grillY + i * slotSpacing, panelW * 0.6, slotSpacing * 0.4, 3);
            ctx.fill();
        }
    }

    // --- Draw Screen CRT ---
    const screenX = startX + margin;
    const screenY = startY + margin;
    
    // Background Cavity (Dark border behind the physical screen)
    ctx.fillStyle = '#0a0a0a';
    drawRoundRect(ctx, screenX - 5, screenY - 5, sw + 10, sh + 10, margin * 0.4);
    ctx.fill();

    // Render image with clipping mask
    ctx.save();
    drawRoundRect(ctx, screenX, screenY, sw, sh, margin * 0.3);
    ctx.clip();
    
    // Fallback black base inside screen
    ctx.fillStyle = '#000';
    ctx.fillRect(screenX, screenY, sw, sh);
    
    // Inject Image
    ctx.drawImage(originalImg, screenX, screenY, sw, sh);

    // Overlay CRT Effects (if requested)
    if (Number(enableCRT) > 0) {
        // Interlaced Scanlines
        ctx.fillStyle = 'rgba(0, 0, 0, 0.25)';
        for (let i = 0; i < sh; i += 3) {
            ctx.fillRect(screenX, screenY + i, sw, 1);
        }
        
        // Curved aesthetic screen glare
        ctx.fillStyle = 'rgba(255, 255, 255, 0.06)';
        ctx.beginPath();
        ctx.moveTo(screenX, screenY);
        ctx.lineTo(screenX + sw, screenY);
        ctx.lineTo(screenX + sw, screenY + sh * 0.4);
        ctx.quadraticCurveTo(screenX + sw * 0.5, screenY + sh * 0.8, screenX, screenY + sh * 0.4);
        ctx.fill();

        // Screen spherical depth vignette
        const radialVignette = ctx.createRadialGradient(
            screenX + sw/2, screenY + sh/2, Math.min(sw, sh) * 0.4,
            screenX + sw/2, screenY + sh/2, Math.max(sw, sh) * 0.75
        );
        radialVignette.addColorStop(0, 'rgba(0,0,0,0)');
        radialVignette.addColorStop(1, 'rgba(0,0,0,0.85)');
        ctx.fillStyle = radialVignette;
        ctx.fillRect(screenX, screenY, sw, sh);
    }
    ctx.restore();

    // Inner Tube Rim highlighting
    ctx.strokeStyle = '#333';
    ctx.lineWidth = 2;
    drawRoundRect(ctx, screenX, screenY, sw, sh, margin * 0.3);
    ctx.stroke();

    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 Television Icon Image Generator allows you to transform any uploaded image into a stylized retro television icon. The tool wraps your image within a vintage CRT-style television frame, complete with features like classic antennae, support legs, hardware panels with dials, and speaker grills. You can customize the aesthetic by adjusting the TV body color and the panel color. For a truly nostalgic look, the tool can apply CRT effects, including interlaced scanlines, screen glare, and a spherical vignette to simulate an old-fashioned tube television. This is ideal for graphic designers, content creators looking for retro aesthetics, or anyone wanting to add a unique, vintage media theme to their digital projects.

Leave a Reply

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