Please bookmark this page to avoid losing your image tool!

YouTube Video To Image Frame Extractor

(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, youtubeUrlOrId = "https://www.youtube.com/watch?v=dQw4w9WgXcQ", frameType = "maxresdefault") {
    return new Promise(async (resolve) => {
        // Robust pattern to extract YouTube Video ID from various URL formats
        function getVideoId(url) {
            if (!url) return null;
            url = String(url).trim();
            // If the input is already exactly an 11-character video ID
            if (url.length === 11 && /^[a-zA-Z0-9_-]{11}$/.test(url)) return url;
            
            let match = url.match(/(?:youtu\.be\/|youtube\.com\/(?:embed\/|v\/|shorts\/|watch\?v=|watch\?.+&v=)|m\.youtube\.com\/watch\?v=)([\w-]{11})/);
            if (!match) {
                match = url.match(/[?&]v=([\w-]{11})/);
            }
            if (!match) {
                match = url.match(/(?:embed|v|shorts)\/([\w-]{11})/);
            }
            return match ? match[1] : null;
        }

        const videoId = getVideoId(youtubeUrlOrId) || "dQw4w9WgXcQ";

        // Validate the requested frameType
        const validTypes = ["maxresdefault", "hqdefault", "mqdefault", "sddefault", "0", "1", "2", "3", "storyboard"];
        if (!validTypes.includes(frameType)) {
            frameType = "maxresdefault";
        }

        // Helper to load images with a graceful fallback for strict CORS environments
        const loadImage = (src) => {
            return new Promise((res) => {
                const img = new Image();
                img.crossOrigin = "anonymous"; // Try securely first (allows clean Canvas export)
                img.onload = () => res({ img, src });
                img.onerror = () => {
                    // Fallback without CORS (will taint canvas, but guarantees display)
                    const fallbackImg = new Image();
                    fallbackImg.onload = () => res({ img: fallbackImg, src });
                    fallbackImg.onerror = () => res(null);
                    fallbackImg.src = src;
                };
                img.src = src;
            });
        };

        // If the user requests a 'storyboard', generate an all-in-one grid with main cover + keyframes
        if (frameType === "storyboard") {
            const coverUrl = `https://img.youtube.com/vi/${videoId}/hqdefault.jpg`;
            const f1Url = `https://img.youtube.com/vi/${videoId}/1.jpg`;
            const f2Url = `https://img.youtube.com/vi/${videoId}/2.jpg`;
            const f3Url = `https://img.youtube.com/vi/${videoId}/3.jpg`;

            const [cover, f1, f2, f3] = await Promise.all([
                loadImage(coverUrl),
                loadImage(f1Url),
                loadImage(f2Url),
                loadImage(f3Url)
            ]);

            if (!cover || !cover.img) {
                const div = document.createElement("div");
                div.style.color = "red";
                div.innerText = "Error loading storyboard frames. Please check the URL.";
                return resolve(div);
            }

            const cvs = document.createElement("canvas");
            // Standard hqdefault is 480x360. Internal keyframes 1, 2, 3 are 120x90.
            cvs.width = 480;
            cvs.height = 360 + 90 + 20; // 360px (cover) + 10px (gap) + 90px (thumbnails) + 10px (bottom margin)
            const ctx = cvs.getContext("2d");

            ctx.fillStyle = "#111111"; // Dark background to tie it together nicely
            ctx.fillRect(0, 0, cvs.width, cvs.height);

            ctx.drawImage(cover.img, 0, 0, 480, 360);
            
            // Align smaller frames evenly across the bottom row
            if (f1 && f1.img) ctx.drawImage(f1.img, 30, 370, 120, 90);
            if (f2 && f2.img) ctx.drawImage(f2.img, 180, 370, 120, 90);
            if (f3 && f3.img) ctx.drawImage(f3.img, 330, 370, 120, 90);

            return resolve(cvs);
        } else {
            // Processing a single frame request
            let imgUrl = `https://img.youtube.com/vi/${videoId}/${frameType}.jpg`;
            let loaded = await loadImage(imgUrl);

            if (!loaded) {
                const div = document.createElement("div");
                div.style.color = "red";
                div.innerText = "Error loading specific video frame.";
                return resolve(div);
            }

            // Fallback for maxresdefault: Many videos do not have a 1080p cover.
            // YouTube returns a 120x90 placeholder image gracefully instead of an HTTP 404.
            // We check for this specific placeholder size and upgrade it to 'hqdefault' automatically.
            if (frameType === "maxresdefault" && loaded.img.width === 120 && loaded.img.height === 90) {
                const hqUrl = `https://img.youtube.com/vi/${videoId}/hqdefault.jpg`;
                const hqLoaded = await loadImage(hqUrl);
                if (hqLoaded && hqLoaded.img) {
                    loaded = hqLoaded;
                }
            }

            const cvs = document.createElement("canvas");
            cvs.width = loaded.img.width;
            cvs.height = loaded.img.height;
            const ctx = cvs.getContext("2d");
            ctx.drawImage(loaded.img, 0, 0);

            return resolve(cvs);
        }
    });
}

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 allows users to extract high-quality still images and frames from YouTube videos using a video URL or ID. Users can choose between various resolution settings, ranging from maximum resolution to standard definition, to get the specific quality they need. Additionally, the tool features a storyboard mode that generates a composite image containing the video’s main cover along with keyframe thumbnails. This is useful for content creators looking to design custom thumbnails, researchers needing visual references from videos, or anyone wanting to quickly capture a snapshot of a specific scene without manual screen capturing.

Leave a Reply

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

Other Image Tools:

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

Video Platform Audio Track Language Translator and Downloader

See All →