Please bookmark this page to avoid losing your image tool!

DVD Video To Image 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.
function processImage(originalImg, statusText = "PLAY \u25BA", timecode = "01:23:45", osdColor = "#33FF33", combingIntensity = "2", videoNoise = "12", addScanlines = "1", addLetterbox = "1", showDVDLogo = "1") {
    const canvas = document.createElement('canvas');
    const width = originalImg.width;
    const height = originalImg.height;
    canvas.width = width;
    canvas.height = height;
    const ctx = canvas.getContext('2d');

    // Draw the original base image
    ctx.drawImage(originalImg, 0, 0, width, height);

    // Parse strength parameters
    const applyCombingValue = parseFloat(combingIntensity) || 0;
    const noiseVal = parseFloat(videoNoise) || 0;
    
    // Apply Interlacing Combing effect and/or video noise to simulate paused DVD video
    if (applyCombingValue > 0 || noiseVal > 0) {
        // Pixel level shift for field combing (horizontal misalignments on alternate rows)
        const shift = Math.floor(applyCombingValue * Math.max(1, width / 400));
        // Standard video has 480 interlaced lines, we map that to the image height
        const fieldHeight = Math.max(1, Math.floor(height / 480)); 
        
        const imgData = ctx.getImageData(0, 0, width, height);
        const data = imgData.data;
        const originalData = new Uint8ClampedArray(data); // clone for reading
        
        for (let y = 0; y < height; y++) {
            const fieldIndex = Math.floor(y / fieldHeight);
            const isEvenField = fieldIndex % 2 === 0;
            const currentShift = isEvenField ? shift : -shift;
            
            for (let x = 0; x < width; x++) {
                let srcX = x - currentShift;
                // Clamp edges to cause realistic video field smearing
                if (srcX < 0) srcX = 0;
                else if (srcX >= width) srcX = width - 1;
                
                const srcIdx = (y * width + srcX) * 4;
                const destIdx = (y * width + x) * 4;
                
                if (noiseVal > 0) {
                    const noise = (Math.random() - 0.5) * noiseVal;
                    // Float implicit conversion handles rounding and clamping on Uint8ClampedArray naturally
                    data[destIdx] = originalData[srcIdx] + noise;
                    data[destIdx+1] = originalData[srcIdx+1] + noise;
                    data[destIdx+2] = originalData[srcIdx+2] + noise;
                    data[destIdx+3] = originalData[srcIdx+3];
                } else {
                    data[destIdx] = originalData[srcIdx];
                    data[destIdx+1] = originalData[srcIdx+1];
                    data[destIdx+2] = originalData[srcIdx+2];
                    data[destIdx+3] = originalData[srcIdx+3];
                }
            }
        }
        ctx.putImageData(imgData, 0, 0);
    }

    // Apply Screen Vignette / Dimmed corners
    const gradient = ctx.createRadialGradient(width/2, height/2, height/3, width/2, height/2, Math.max(width, height));
    gradient.addColorStop(0, 'rgba(0,0,0,0)');
    gradient.addColorStop(1, 'rgba(0,0,0,0.5)');
    ctx.fillStyle = gradient;
    ctx.fillRect(0, 0, width, height);

    // Apply Cinematic Letterboxing
    const isLetterbox = String(addLetterbox).toLowerCase() === "1" || String(addLetterbox).toLowerCase() === "true";
    if (isLetterbox) {
        const barHeight = Math.floor(height * 0.12);
        ctx.fillStyle = "#000000";
        ctx.fillRect(0, 0, width, barHeight);
        ctx.fillRect(0, height - barHeight, width, barHeight);
    }

    // Apply CRT Over-layer Scanlines
    const isScanlines = String(addScanlines).toLowerCase() === "1" || String(addScanlines).toLowerCase() === "true";
    if (isScanlines) {
        const lineStep = Math.max(2, Math.floor(height / 360)); 
        const lineThickness = Math.max(1, Math.floor(lineStep / 2.5));
        ctx.fillStyle = "rgba(0, 0, 0, 0.25)";
        for (let y = 0; y < height; y += lineStep) {
            ctx.fillRect(0, y, width, lineThickness);
        }
    }

    // OSD / TEXT RENDERING
    const fontSize = Math.max(16, Math.floor(height * 0.05));
    const paddingY = Math.max(15, Math.floor(height * 0.05));
    const paddingX = Math.max(15, Math.floor(width * 0.05));

    function drawText(text, x, y, align = "left", baseline = "top") {
        ctx.font = `bold ${fontSize}px "Courier New", Courier, monospace`;
        ctx.textAlign = align;
        ctx.textBaseline = baseline;
        
        // Draw heavy black stroke for retro visibility
        ctx.shadowColor = 'transparent';
        ctx.shadowBlur = 0;
        ctx.lineWidth = Math.max(2, Math.floor(fontSize * 0.15));
        ctx.strokeStyle = 'black';
        ctx.lineJoin = 'round';
        ctx.strokeText(text, x, y);

        // Draw inner colored text with native glow
        ctx.fillStyle = osdColor;
        ctx.shadowColor = osdColor;
        ctx.shadowBlur = Math.max(4, fontSize * 0.25);
        ctx.fillText(text, x, y);
        
        // Reset Shadow for subsequent drawings
        ctx.shadowBlur = 0;
    }

    if (statusText && statusText.trim() !== "") {
        drawText(statusText, paddingX, paddingY, "left", "top");
    }
    
    if (timecode && timecode.trim() !== "") {
        drawText(timecode, width - paddingX, paddingY, "right", "top");
    }

    // Custom DVD Logo Render
    const isShowLogo = String(showDVDLogo).toLowerCase() === "1" || String(showDVDLogo).toLowerCase() === "true";
    if (isShowLogo) {
        function drawDVDLogo(x, y, h) {
            ctx.save();
            ctx.translate(x, y);
            const logoW = h * 2.5;
            const logoH = h;
            
            // Multiple render passes for intense black stroke logic
            ctx.shadowColor = 'black';
            ctx.shadowBlur = Math.max(2, h * 0.1);
            ctx.lineJoin = 'round';
            
            for(let i = 0; i < 3; i++) {
                ctx.beginPath();
                ctx.ellipse(logoW/2, logoH*0.65, logoW/2, logoH*0.25, 0, 0, 2 * Math.PI);
                ctx.strokeStyle = 'black';
                ctx.lineWidth = Math.max(2, h*0.12);
                ctx.stroke();
                
                ctx.font = `italic bold ${h * 0.8}px "Arial Black", Arial, sans-serif`;
                ctx.textAlign = 'center';
                ctx.textBaseline = 'middle';
                ctx.lineWidth = Math.max(2, h*0.15);
                ctx.strokeText("DVD", logoW/2, logoH*0.35);
                
                ctx.font = `bold ${h * 0.22}px "Arial", sans-serif`;
                ctx.strokeText("V I D E O", logoW/2, logoH*0.95);
            }

            // Fill color and apply neon glow
            ctx.shadowColor = osdColor;
            ctx.shadowBlur = Math.max(3, h * 0.2);
            ctx.strokeStyle = osdColor;
            ctx.fillStyle = osdColor;
            
            ctx.beginPath();
            ctx.ellipse(logoW/2, logoH*0.65, logoW/2, logoH*0.25, 0, 0, 2 * Math.PI);
            ctx.lineWidth = Math.max(1, h*0.04);
            ctx.stroke();

            ctx.font = `italic bold ${h * 0.8}px "Arial Black", Arial, sans-serif`;
            ctx.fillText("DVD", logoW/2, logoH*0.35);
            
            ctx.font = `bold ${h * 0.22}px "Arial", sans-serif`;
            ctx.fillText("V I D E O", logoW/2, logoH*0.95);
            
            ctx.restore();
        }

        const logoHeight = Math.max(20, Math.floor(height * 0.08));
        drawDVDLogo(paddingX, height - paddingY - (logoHeight * 1.1), logoHeight);
    }

    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 DVD Video To Image Converter is a creative tool designed to transform standard images into visuals that mimic the appearance of a paused DVD player. It applies several retro video effects, including interlacing combing, video noise, CRT-style scanlines, and cinematic letterboxing. Users can also customize On-Screen Display (OSD) elements such as playback status text, timecodes, and a glowing DVD logo with adjustable colors. This tool is ideal for graphic designers, content creators, or anyone looking to add a nostalgic, lo-fi aesthetic to their digital imagery for social media, presentations, or artistic projects.

Leave a Reply

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