How can I extract a good quality JPEG image from a video file with ffmpeg?
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
- FFmpeg FAQ: How do I encode movie to single pictures?
- FFmpeg Wiki: Create a thumbnail image every X seconds of the video
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.
![Daniel Gartmann](https://i.stack.imgur.com/8sVAs.jpg?s=256&g=1)
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, 2021Comments
-
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 over 9 yearsThis 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 about 9 yearsCan 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 about 9 yearsFor 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 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 over 6 years@Kostanos You can try
-qmin 1 -q:v 1
. -
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 over 5 years@BhuvneshVarma Because, if I recall correctly (can't check at the moment),
-qmin
default is2
. You can try-q:v 1
if you add-qmin 1
. -
lapin over 4 years
ffmpeg
outputsPNG8
files which use only 256 colors (same as GIF). so it is actually very lossy. -
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 offfmpeg
are you using that is outputtingPNG8
files, and what is your input format? -
lapin over 4 yearsActually 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 averageidentify
user is supposed to understand that tho. -
Luis A. Florit almost 4 yearsGot 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 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 almost 4 yearsIndeed, sorry, I was confused by the error message "Supported codecs are: mjpeg".
-
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 over 3 yearsI found your solution working to generate high quality key-frames, nonetheless I think that it must be arranged in a more clearer way.
-
pouya over 2 yearsNo 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 over 2 years@BalrogOfMoria I edited my answer to make it more clear, thanks for the feedback.
-
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 yearsIt is better to extract .png and then use mozjpeg with better jpeg algos.
-
Валерий Заподовников over 2 yearsJust use lossless jpeg or jpeg ls or jpeg 2000 lossless.