How can I extract a good quality JPEG image from a video file with ffmpeg?

166,440

Solution 1

Use -qscale:v to control quality

Use -qscale:v (or the alias -q:v) as an output option.

  • Normal range for JPEG is 2-31 with 31 being the worst quality.
  • The scale is linear with double the qscale being roughly half the bitrate.
  • Recommend trying values of 2-5.
  • You can use a value of 1 but you must add the -qmin 1 output option (because the default is -qmin 2).

To output a series of images:

ffmpeg -i input.mp4 -qscale:v 2 output_%03d.jpg

See the image muxer documentation for more options involving image outputs.

To output a single image at ~60 seconds duration:

ffmpeg -ss 60 -i input.mp4 -qscale:v 4 -frames:v 1 output.jpg

To continuously overwrite/update/save to a single image

Use -update 1 image muxer option. Example for once per second from a live streaming input:

ffmpeg -i rtmp://input.foo -q:v 4 -r 1 -update 1 output.jpg

Also see

Solution 2

Output the images in a lossless format such as PNG:

mkdir stills
ffmpeg -i my-film.mp4 -vsync 0 -f image2 stills/my-film-%06d.png

Then use another program (where you can more precisely specify quality, subsampling and DCT method – e.g. GIMP) to convert the PNGs you want to JPEG.

It is possible to obtain slightly sharper images in JPEG format this way than is possible with -qmin 1 -q:v 1 and outputting as JPEG directly from ffmpeg.

If you want to extract only the key frames (which are likely to be of higher quality post-edit) you can use something like this:

ffmpeg -skip_frame nokey -i my-film.mp4 -vsync 0 -f image2 stills/my-film-%06d.png

The -vsync 0 parameter avoids needing to specify the frame rate with -r and means all frames in the input file are treated as, um, a frame.

Share:
166,440
Daniel Gartmann
Author by

Daniel Gartmann

I am an IT-Security expert with a software development background that helps companies innovate and meet their strategic goals by turning security into an enabler and not a blocker.

Updated on April 21, 2021

Comments

  • Daniel Gartmann
    Daniel Gartmann about 3 years

    Currently I am using this command to extract the images:

    ffmpeg -i input.mp4 output_%03d.jpeg
    

    But how can I improve the JPEG image quality?

  • felwithe
    felwithe over 9 years
    This seems to have no effect for me-- qscale 1 and 2 both give identical file sizes and (to my naked eye) appear the same as without qscale at all.
  • Ronald S. Bultje
    Ronald S. Bultje about 9 years
    Can you post the complete commandline you're using? Also please post the complete, uncut output from ffmpeg on the commandline. Note that placement of options is relevant, so -qscale:v 2 needs to be placed after the -i inputfile option, but before the output file option, to have any effect.
  • complistic
    complistic about 9 years
    For me adding -qmin 1 -qmax 1 in addition to -q:v 1 doubled the file size. And I can seem to see a very slight improvement also.
  • cherouvim
    cherouvim over 8 years
    @complistic: -qmin 1 -qmax 1 resulted in larger file, but gives me an exact same image. I validated this via photoshop, 2 layers and difference filter. The pixels are the same.
  • llogan
    llogan over 6 years
    @Kostanos You can try -qmin 1 -q:v 1.
  • Android Developer
    Android Developer over 5 years
    @LordNeckbeard "Effective range for JPEG is 2-31 with 31 being the worst quality"..why -q:v 1 not in effective range?
  • llogan
    llogan over 5 years
    @BhuvneshVarma Because, if I recall correctly (can't check at the moment), -qmin default is 2. You can try -q:v 1 if you add -qmin 1.
  • lapin
    lapin over 4 years
    ffmpeg outputs PNG8 files which use only 256 colors (same as GIF). so it is actually very lossy.
  • Jake
    Jake over 4 years
    @lapin The PNGs I extracted using this method are 24 bit (even for frames with fewer than 256 colours, though others have many more). This was using version 4.2.1 x64 on Windows. Also written here is: "If I pull png's from an mp4, with this [ffmpeg] command, I get high quality png's that are of identical quality to the original video." What version of ffmpeg are you using that is outputting PNG8 files, and what is your input format?
  • lapin
    lapin over 4 years
    Actually I think you're right, the problem was that identify image.png gives result "8-bit" when actually its not really single channel 8-bit, but 8-bit for R, G and B. IDK how the average identify user is supposed to understand that tho.
  • Luis A. Florit
    Luis A. Florit almost 4 years
    Got an error with your last command: Codec 'h264' (27) is not supported by the bitstream filter 'mjpeg2jpeg'. Supported codecs are: mjpeg (7) Error initializing bitstream filter: mjpeg2jpeg.
  • llogan
    llogan almost 4 years
    @LuisA.Florit That command is only for MJPEG inputs: "If your input is MJPEG (Motion JPEG) then the images can be extracted without any quality loss." Your input appears to be H.264, so you'll have to use the first command.
  • Luis A. Florit
    Luis A. Florit almost 4 years
    Indeed, sorry, I was confused by the error message "Supported codecs are: mjpeg".
  • Jake
    Jake over 3 years
    @DonnyV. You can't get downvoted for a comment (only 'flagged as inapporpriate'). Glad this helped. Thanks for reminding me I posted this. I've rechecked the example command I gave and updated my answer to offer some better alternatives that are more akin to what I'm using now I know a bit more about ffmpeg.
  • BalrogOfMoria
    BalrogOfMoria over 3 years
    I found your solution working to generate high quality key-frames, nonetheless I think that it must be arranged in a more clearer way.
  • pouya
    pouya over 2 years
    No matter which format you use ffmeg downgrades image quality. With -qmin 1 -q:v 1 JPG quality is the same as PNG quality. Both suck.
  • Jake
    Jake over 2 years
    @BalrogOfMoria I edited my answer to make it more clear, thanks for the feedback.
  • Jake
    Jake over 2 years
    @pouya Can you get anything better when you pause the video during playback? If not, then you don't have a good enough quality copy of the original video for what you are trying to do. I have seen the source code where ffmpeg sets the JPEG compression quality to 90 (instead of 70) if you have -q2 set, but that is still lower than I would normally use. Also note it is recompressing a still from a movie that has already been compressed, and that 'key frames' will be of better quality. But whilst MPEG is based on JPEG, it seems not possible to lift even key frames directly as JPEG images.
  • Валерий Заподовников
    Валерий Заподовников over 2 years
    It is better to extract .png and then use mozjpeg with better jpeg algos.
  • Валерий Заподовников
    Валерий Заподовников over 2 years
    Just use lossless jpeg or jpeg ls or jpeg 2000 lossless.