I've read a few answers and articles on using programs like VLC, MPlayer, ffmpeg, etc., but none of the methods I've seen are "lossless." They don't capture every single frame. I want to extract each frame from a video as an image (100% quality, I don't want to lose any detail), so one could theoretically take those images and re-create the video file without being able to tell the difference from the original (excluding the lack of audio, of course).

Bonus points if I can specify a start and end time to grab frames from, so I don't have to crop the video file beforehand.


4 Answers 4


You can extract the frames as PNG, a lossless picture compression format. For example, to extract frames from the 5min mark to the 10min mark :

ffmpeg -ss 05:00 -i <input> -t 05:00 filename%05d.png
  • 1
    I get the error Output file is empty, nothing was encoded (check -ss / -t / -frames parameters if used)
    – Caridorc
    Mar 23, 2019 at 21:36
  • 4
    ffmpeg outputs PNG8 files, which are not lossless, it's only 256 colors (same as GIF !! Only PNG24 are lossless. .bmp would be a lossless option for ffmpeg
    – lapin
    Feb 17, 2020 at 6:42
  • would you mind clarifying what %05d is? I see other use %00d ? Thanks!
    – Matifou
    Oct 16, 2020 at 0:14
  • 1
    %05d is correct. It means number the files and use a 5 digit zero-padded naming convention.
    – Rajib
    Jan 2, 2022 at 5:20

There are several tools that should be able to extract all frames from a movie file:

avconv -i file.avi -f image2 Out%00d.jpg

ffmpeg -i input.file thumb%04d.png -hide_banner

This can also export BMP, which take much less processing time than PNG or JPG.

There is also a bash script called mov2frame.sh that tries to automate the FFMPEG extraction process.

mplayer -ao null -vo png input.file

or another option:

mplayer -nosound -vo png:z=9 my_file.mp4

VLC This media player apparently can export image sets using its filters, but seems troublesome unless it's your only usage or you have a portable version.

  1. Create a folder to store your frames and copy the path to it. For Mac OSX/Linux users, this must be the full path (no ~).

  2. Click Tools / Preferences in VLC.

  3. Under “show settings”, click “all”.

  4. Under “Video”, select “Filters”. Tick “Scene video filter”.

  5. Expand “Filters” and select “Scene filter”,

  6. Paste the path from earlier into “directory path prefix”.

  7. Choose the fraction of frames to encode in the “recording ratio” box. 1/12 with output every 12, 1/1 will export them all

  8. Click “save”.

  9. Click Media / Open Video and find your video. Patiently let the whole thing play.

  10. Click Tools / Preferences. Under “show settings”, click “all”. Under “video”, select “filters”. Uncheck “Scene video filter”. Click “save”. This is so that VLC won’t generate thumbnails the next time you play a video. link

There also appears to be some potential trouble with admin permissions on first program run:

sudo vlc [sudo] password for mint16: VLC is not supposed to be run as root. Sorry. If you need to use real-time priorities and/or privileged TCP ports you can use vlc-wrapper (make sure it is Set-UID root and cannot be run by non-trusted users first).

VLC also performs much better when extracting to BMP instead of PNG

  • How can I reduce the framerate output using ffmpeg? Can I have for example only 2 images of frames per second?
    – Caridorc
    Mar 23, 2019 at 21:43

When doing this with ffmpeg, I have found that I often need to use the -vsync 0 option (for example, when working with some VOB files from DVDs):

ffmpeg -i video.VOB -vsync 0 %06d.bmp

If you want to do a start and stop time too, it would look something like this:

ffmpeg -i video.VOB -vsync 0 -ss 01:30 -to 01:40 %06d.bmp

Below is the code in opencv that worked for me to extract frames from video.

import cv2
import os

# Replace 'your_video_file.mp4' with the path to your video file
video_path = 'your_video_file.mp4'

# Create a VideoCapture object
cap = cv2.VideoCapture(video_path)

# Check if the video file is opened successfully
if not cap.isOpened():
    print("Error: Could not open video file.")

# Create a directory to store the frames
output_directory = 'frames'
os.makedirs(output_directory, exist_ok=True)

# Loop to read frames from the video
frame_count = 0
while True:
    # Read a frame from the video
    ret, frame = cap.read()

    # Check if the frame is read successfully
    if not ret:
        print("End of video.")

    # Save the frame as an image file
    frame_filename = os.path.join(output_directory, f'frame_{frame_count:04d}.png')
    cv2.imwrite(frame_filename, frame)

    frame_count += 1

# Release the VideoCapture object

print(f"{frame_count} frames saved in '{output_directory}'.")

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .