<h1>Just mux the images</h1>

<p>You can simply mux the JPG images to make a video:</p>

<pre><code>ffmpeg -framerate 30 -i input%03d.jpg -codec copy output.mkv
</code></pre>

<p>Note that if you omit <code>-framerate</code> then a default of <code>-framerate 25</code> will be applied to the input.</p>

<h1>Lossless optimization</h1>

<p>You can use <code>jpegtran</code> to perform lossless optimization on each frame which <em>may</em> provide significant file size savings:</p>

<pre><code>mkdir outputdir
for f in *.jpg; do jpegtran -optimize -copy none -perfect -v "$f" &gt; "outputdir/$f"; done
</code></pre>

<p>Now mux with <code>ffmpeg</code> as shown above.</p>

<h1>Checking that it is actually lossless</h1>

<p>The <a href="https://ffmpeg.org/ffmpeg-formats.html#framehash" rel="noreferrer">framehash muxer</a> can be used to compare the unique hash of each frame to ensure that the result is truly lossless:</p>

<pre><code>$ ffmpeg -i input%03d.jpg -f framehash -
stream_index, packet_dts, packet_pts, packet_duration, packet_size, hash
0,          0,          0,        1,   460800, 29bcc2db3726c7dfec1826c5740f603f
0,          1,          1,        1,   460800, b5fdc23d93cbd043dc2b9290dc8378f0
0,          2,          2,        1,   460800, ee0709942f24b458fd2380d134dcb59d
...

$ ffmpeg -i output.mkv -map 0:v -f framehash -
stream_index, packet_dts, packet_pts, packet_duration, packet_size, hash
0,          0,          0,        1,   460800, 29bcc2db3726c7dfec1826c5740f603f
0,          1,          1,        1,   460800, b5fdc23d93cbd043dc2b9290dc8378f0
0,          2,          2,        1,   460800, ee0709942f24b458fd2380d134dcb59d
...
</code></pre>

<p>In the above examples each associated frame for the input and output share the same hash ensuring that the frames are identical and that the output is lossless.</p>

<h1>Also see</h1>

<ul>
<li><a href="http://ffmpeg.org/faq.html#How-do-I-encode-single-pictures-into-movies_003f" rel="noreferrer">FFmpeg image file demuxer documentation</a></li>
<li><a href="http://ffmpeg.org/faq.html#How-do-I-encode-single-pictures-into-movies_003f" rel="noreferrer">FFmpeg Wiki: How do I encode single pictures into movies?</a></li>
</ul>

CC BY-SA 3.0
2013-05-18T08:54:29.140Z
could you please clarify what the two `framemd5` commands are supposed to achieve beyond merely listing the hashes? how would I get additional compression when identical frames are thus identified?
GJ.
CC BY-SA 3.0
2013-05-18T18:24:39.733Z
The hashes were included only to show you that the frames are the same as the individual images, so therefore achieving your requirement of storing "each individual jpg frames as-is (without recompression)".
llogan
CC BY-SA 3.0
2015-01-15T10:05:37.547Z
Posted an answer of my own with an untested idea for dropping the duplicate frames, to end up with a VFR MJPEG.mkv.  VFR is the only way I can think of to take advantage of temporal redundancy with MJPEG. :P
Peter Cordes
CC BY-SA 3.0
2016-06-22T20:22:38.257Z
SSIM may be a quicker way to compare fidelity.
Gyan
CC BY-SA 3.0
2013-05-17T23:06:58.243Z
2016-06-22T20:13:18.667Z
2016-06-22T20:13:18.667Z
llogan
<p>This will output a lossless H.264 video where frames will use information from other frames</p>

<p><code>ffmpeg -f image2 -r 30 -i %09d.jpg -vcodec libx264 -profile:v high444 -refs 16 -crf 0 -preset ultrafast a.mp4</code></p>

<p>Explanation of options:</p>

<ul>
<li><code>-f image2</code> - tells ffmpeg to select a group of images</li>
<li><code>-r 30</code> - tells ffmpeg to encode at 30 frames (or images) per second (change this to your desired framerate)</li>
<li><code>-i %09d.jpg</code> - tells ffmpeg to use the images 000000000.jpg to 999999999.jpg as the input. Change the <code>9</code> in <code>%09d.jpg</code> to how many zeroes the names of your image sequence has. If your file names are, for example, img0001.jpg, then this would be expressed as img%04d.jpg</li>
<li><code>-vcodec libx264</code> - tells ffmpeg to output to a H.264 compliant file</li>
<li><code>-profile:v high444</code> - tells libx264 to use the High 4:4:4 Predictive Lossless profile, allowing lossless encoding</li>
<li><code>-refs 16</code> - tells libx264 to have 16 images stored in a buffer, so that they may be referenced by other images in the video</li>
<li><code>-crf 0</code> - tells libx264 to perform a lossless encode</li>
<li><code>-preset ultrafast</code> - tells libx264 to prioritise encoding speed over output file size</li>
<li><code>a.mp4</code> - tells ffmpeg to save the output in an MP4 file called a.mp4. Change this to the file name and format that you wish to use</li>
</ul>

CC BY-SA 3.0
2015-01-03T22:55:32.790Z
A few notes: `-f image2` is superfluous here. The [image file demuxer](https://ffmpeg.org/ffmpeg-formats.html#image2-1) should use `-framerate` instead of `-r`. libx264 will automatically choose the appropriate `-profile` for lossless, and the `-preset` will deal with `-refs`.
llogan
CC BY-SA 3.0
2015-01-17T14:16:04.810Z
`-refs 5` at MOST, unless you know your content has identical images separated by several other ones, that might cause x264 to lose the reference before it gets to the duplicate.  Higher than `ultrafast` makes little different in lossless mode, other than CABAC's ~10% gain over CAVLC (for a high cpu cost at the bitrates required for lossless).  Seriously, on some live-action 720x480p60 (deinterlace output), `superfast` was 28GB, `slower` was 27GB.  If encode time doesn't matter, but decode time does, make sure you avoid CABAC.  Maybe even `-tune fastdecode`.  Moderate ref count shouldn't hurt.
Peter Cordes
CC BY-SA 3.0
2016-06-22T19:14:33.420Z
And if you have CPU to burn, you can even try `-preset placebo` for a few extra fractions of percent.
DrYak
CC BY-SA 3.0
2016-06-22T19:19:44.987Z
Also for completeness h265 also has its own lossless mode.
`-vcodec libx265 -x265-params lossless=1` is the equivalent option.

(But in my experience (= recording of Powerpoint slideshow presentations), it isn't necessarily better, and it's much slower than h264)

Stay tune for next year's AOMedia's AV1/IETF's NETVC1/Xiph's Daala/whatever it's going to be renamed by then...'s lossless mode
DrYak
CC BY-SA 4.0
2020-07-26T17:15:20.410Z
God bless you !
AdamSkywalker
CC BY-SA 3.0
2015-01-03T18:57:02.883Z
2015-01-03T18:57:02.883Z
Adam Chance
<p>You can create an <code>avi</code> animation as a series of <code>png</code> images ( <code>png</code> <em>is</em> lossless so the <code>jpeg =&gt; png</code> conversion should not degrade your pictures ):</p>

<p>if your images a named <code>img_0001.jpg</code></p>

<pre><code>ffmpeg -r 25 -start_number 1 -f image2 -i "img_%04d.jpg" -vcodec png video.avi
</code></pre>

<p>where "25" is the frame rate you want in the resulting video. <code>-start_number</code> is not needed if it is 1, but it is useful if your first video number is not 1.</p>

<p>If you want to encode in <code>mjpeg</code> with highest quality command line is:</p>

<pre><code>ffmpeg -r 25 -start_number 1 -f image2 -i "img_%04d.jpg" -vcodec mjpeg -qscale 1 video.avi
</code></pre>

<p>And the beauty of the thing is that you can convert the video back to a series a pictures:</p>

<pre><code>ffmpeg -i video.avi "img_series_%04d.png"
ffmpeg -i video.avi "img_series_%04d.jpg"
</code></pre>

<p>etc...</p>

CC BY-SA 3.0
2013-05-17T13:17:53.403Z
This doesn't really meet the askers needs.  He is looking for a way that the frame can be updated loselessly only when the image changes.  This means the same image may be used more than once.  Also jpeg by nature isn't lossless as I believe it uses jpeg compression even at max quality.
AJ Henderson
CC BY-SA 3.0
2013-05-17T13:20:30.723Z
Actually I guess he was willing to have some compression, though I'm not sure how it is going to do on long sequences of the same frame.  I still think a variable frame rate presentation format is what is needed though I'm not sure if ffmpeg supports any.
AJ Henderson
CC BY-SA 3.0
2013-05-17T18:51:46.240Z
CorePNG is able to create P frames also. Usually jpeg is not a lossless compression, and I doubt mjpeg can create P frames. I agree I do not answer the question as it is asked, but I give a solution to have a lossless video with ffmpeg.
Olivier S
CC BY-SA 3.0
2013-05-17T04:54:46.163Z
2013-05-17T12:06:31.270Z
2013-05-17T12:06:31.270Z
Olivier S
<p>To expand on LordNeckbeard's answer, yes, just mux the JPEG data into an MJPEG video stream.  That will be the smallest representation of the exact sequence of output images, even though MJPEG is a terribly inefficient codec by today's standards.  (no temporal redundancy, and not even any intra prediction.</p>

<p>You can make a variable-framerate MJPEG video to take advantage of the duplicate images in your input.</p>

<pre><code>ffmpeg -framerate 30 -i input%03d.jpg -vf mpdecimate -codec copy output.mkv  # doesn't work.
</code></pre>

<p>Hrm, this isn't going to work, since mpdecimate won't work on compressed data, and we can't let ffmpeg decode and then re-jpeg the image data without loss and CPU cost.</p>

<p>Maybe if you replaced duplicate jpg source files with empty files with that sequence number, or something?</p>

<p>Since this question isn't even recent, I'm not going to take the time to figure out how to do it unless someone replies to ask how.  But since MJPEG can go into an mkv container, I'm sure it's possible to have a file that doesn't duplicate the jpeg data for repeated frames, but instead just doesn't have an output frame to decode until the sequence of duplicates is over.</p>

<p>Oh here's an idea:</p>

<pre><code>ffmpeg -framerate blah -input blah -vf mpdecimate -f mkvtimestamp_v2 mpdecimate.timestamps
</code></pre>

<p>Then remove (or move aside) all the jpegs for frames that mpdecimate wants to drop (probably it has some logging options?  Or -vf showinfo, and parse that, and move or hardlink only the frames that show up in its output, leaving behind the dropped JPEGs?).  mux that to a MJPEG.mkv, then do something with mkvmerge to replace the frame timestamps in that with the timestamps from <code>mpdecimate.timestamps</code>.</p>

<p>If you were xcoding, instead of just muxing jpeg data to MJPEG, this would be MUCH easier, since you'd just use my first command with mpdecimate and any codec other than <code>copy</code>, and it would Just Work(tm).</p>

<p>I haven't tried any of this, since this was an old question.  Also the reason I haven't filled in the gaps of how to actually filter your directory of jpegs based on mpdecimate output, or how to actually use the timestamp stream.</p>

CC BY-SA 3.0
2015-01-15T10:03:38.860Z
2015-01-15T10:03:38.860Z
Peter Cordes
<p>I have a large set of jpgs that I want to convert to a video losslessly (or, at the very least, very close to losslessly as long as the encoding time isn't much higher than otherwise).</p>

<p>Naively, I would think that there should be some codec that can store each individual jpg frames as-is (without recompression), and perhaps achieve some nice compression by replacing some of the frames by just the information on the delta from the previous frame. In my case there are many sequences of frames which are identical to each other, or that have a tiny difference between them.</p>

<p>Is there some codec and suitable settings for ffmpeg that can achieve this?</p>

CC BY-SA 3.0
2013-05-16T20:36:07.867Z
Related: http://avp.stackexchange.com/questions/4642/batch-processing-individual-frames-into-video/6853#6853
Friend Of George
CC BY-SA 3.0
2013-05-16T20:36:15.883Z
Also Related: http://avp.stackexchange.com/questions/7300/how-to-get-ffmpeg-to-join-non-sequential-image-files-skip-by-3s
Friend Of George
CC BY-SA 3.0
2015-01-15T09:44:06.767Z
sequence-of-jpegs has been a codec for a LONG time.  Digital cameras that don't use h.264 invariably record MJPEG, and video capture cards used to use it, I think.
Peter Cordes
<video><ffmpeg><encoding>
How to losslessly encode a jpg image sequence to a video in ffmpeg?
GJ.
# How to losslessly encode a jpg image sequence to a video in ffmpeg?

(Asked by: username_0 on 2013-05-16)

I have a large set of jpgs that I want to convert to a video losslessly (or, at the very least, very close to losslessly as long as the encoding time isn't much higher than otherwise).

Naively, I would think that there should be some codec that can store each individual jpg frames as-is (without recompression), and perhaps achieve some nice compression by replacing some of the frames by just the information on the delta from the previous frame. In my case there are many sequences of frames which are identical to each other, or that have a tiny difference between them.

Is there some codec and suitable settings for ffmpeg that can achieve this?

**Tags:** video, ffmpeg, encoding

> **Comments:**
> **username_1**: Related: http://avp.stackexchange.com/questions/4642/batch-processing-individual-frames-into-video/6853#6853  
> **username_1**: Also Related: http://avp.stackexchange.com/questions/7300/how-to-get-ffmpeg-to-join-non-sequential-image-files-skip-by-3s  
> **username_2**: sequence-of-jpegs has been a codec for a LONG time.  Digital cameras that don't use h.264 invariably record MJPEG, and video capture cards used to use it, I think.  

---

## 4 answers

### Answer by username_3 on 2013-05-17. Score: 42

Just mux the images
You can simply mux the JPG images to make a video:
ffmpeg -framerate 30 -i input%03d.jpg -codec copy output.mkv

Note that if you omit -framerate then a default of -framerate 25 will be applied to the input.
Lossless optimization
You can use jpegtran to perform lossless optimization on each frame which may provide significant file size savings:
mkdir outputdir
for f in *.jpg; do jpegtran -optimize -copy none -perfect -v "$f" > "outputdir/$f"; done

Now mux with ffmpeg as shown above.
Checking that it is actually lossless
The framehash muxer can be used to compare the unique hash of each frame to ensure that the result is truly lossless:
$ ffmpeg -i input%03d.jpg -f framehash -
stream_index, packet_dts, packet_pts, packet_duration, packet_size, hash
0,          0,          0,        1,   460800, 29bcc2db3726c7dfec1826c5740f603f
0,          1,          1,        1,   460800, b5fdc23d93cbd043dc2b9290dc8378f0
0,          2,          2,        1,   460800, ee0709942f24b458fd2380d134dcb59d
...

$ ffmpeg -i output.mkv -map 0:v -f framehash -
stream_index, packet_dts, packet_pts, packet_duration, packet_size, hash
0,          0,          0,        1,   460800, 29bcc2db3726c7dfec1826c5740f603f
0,          1,          1,        1,   460800, b5fdc23d93cbd043dc2b9290dc8378f0
0,          2,          2,        1,   460800, ee0709942f24b458fd2380d134dcb59d
...

In the above examples each associated frame for the input and output share the same hash ensuring that the frames are identical and that the output is lossless.
Also see

FFmpeg image file demuxer documentation
FFmpeg Wiki: How do I encode single pictures into movies?

> **Comments:**
> **username_0**: could you please clarify what the two `framemd5` commands are supposed to achieve beyond merely listing the hashes? how would I get additional compression when identical frames are thus identified?  
> **username_3**: The hashes were included only to show you that the frames are the same as the individual images, so therefore achieving your requirement of storing "each individual jpg frames as-is (without recompression)".  
> **username_2**: Posted an answer of my own with an untested idea for dropping the duplicate frames, to end up with a VFR MJPEG.mkv.  VFR is the only way I can think of to take advantage of temporal redundancy with MJPEG. :P  
> **username_4**: SSIM may be a quicker way to compare fidelity.  

---

### Answer by username_5 on 2015-01-03. Score: 14

This will output a lossless H.264 video where frames will use information from other frames

`ffmpeg -f image2 -r 30 -i %09d.jpg -vcodec libx264 -profile:v high444 -refs 16 -crf 0 -preset ultrafast a.mp4`

Explanation of options:

* `-f image2` - tells ffmpeg to select a group of images
* `-r 30` - tells ffmpeg to encode at 30 frames (or images) per second (change this to your desired framerate)
* `-i %09d.jpg` - tells ffmpeg to use the images 000000000.jpg to 999999999.jpg as the input. Change the `9` in `%09d.jpg` to how many zeroes the names of your image sequence has. If your file names are, for example, img0001.jpg, then this would be expressed as img%04d.jpg
* `-vcodec libx264` - tells ffmpeg to output to a H.264 compliant file
* `-profile:v high444` - tells libx264 to use the High 4:4:4 Predictive Lossless profile, allowing lossless encoding
* `-refs 16` - tells libx264 to have 16 images stored in a buffer, so that they may be referenced by other images in the video
* `-crf 0` - tells libx264 to perform a lossless encode
* `-preset ultrafast` - tells libx264 to prioritise encoding speed over output file size
* `a.mp4` - tells ffmpeg to save the output in an MP4 file called a.mp4. Change this to the file name and format that you wish to use

> **Comments:**
> **username_3**: A few notes: `-f image2` is superfluous here. The [image file demuxer](https://ffmpeg.org/ffmpeg-formats.html#image2-1) should use `-framerate` instead of `-r`. libx264 will automatically choose the appropriate `-profile` for lossless, and the `-preset` will deal with `-refs`.  
> **username_2**: `-refs 5` at MOST, unless you know your content has identical images separated by several other ones, that might cause x264 to lose the reference before it gets to the duplicate.  Higher than `ultrafast` makes little different in lossless mode, other than CABAC's ~10% gain over CAVLC (for a high cpu cost at the bitrates required for lossless).  Seriously, on some live-action 720x480p60 (deinterlace output), `superfast` was 28GB, `slower` was 27GB.  If encode time doesn't matter, but decode time does, make sure you avoid CABAC.  Maybe even `-tune fastdecode`.  Moderate ref count shouldn't hurt.  
> **username_6**: And if you have CPU to burn, you can even try `-preset placebo` for a few extra fractions of percent.  
> **username_6**: Also for completeness h265 also has its own lossless mode. `-vcodec libx265 -x265-params lossless=1` is the equivalent option.  (But in my experience (= recording of Powerpoint slideshow presentations), it isn't necessarily better, and it's much slower than h264)  Stay tune for next year's AOMedia's AV1/IETF's NETVC1/Xiph's Daala/whatever it's going to be renamed by then...'s lossless mode  
> **username_7**: God bless you !  

---

### Answer by username_8 on 2013-05-17. Score: 6

You can create an avi animation as a series of png images ( png is lossless so the jpeg => png conversion should not degrade your pictures ):
if your images a named img_0001.jpg
ffmpeg -r 25 -start_number 1 -f image2 -i "img_%04d.jpg" -vcodec png video.avi

where "25" is the frame rate you want in the resulting video. -start_number is not needed if it is 1, but it is useful if your first video number is not 1.
If you want to encode in mjpeg with highest quality command line is:
ffmpeg -r 25 -start_number 1 -f image2 -i "img_%04d.jpg" -vcodec mjpeg -qscale 1 video.avi

And the beauty of the thing is that you can convert the video back to a series a pictures:
ffmpeg -i video.avi "img_series_%04d.png"
ffmpeg -i video.avi "img_series_%04d.jpg"

etc...

> **Comments:**
> **username_9**: This doesn't really meet the askers needs.  He is looking for a way that the frame can be updated loselessly only when the image changes.  This means the same image may be used more than once.  Also jpeg by nature isn't lossless as I believe it uses jpeg compression even at max quality.  
> **username_9**: Actually I guess he was willing to have some compression, though I'm not sure how it is going to do on long sequences of the same frame.  I still think a variable frame rate presentation format is what is needed though I'm not sure if ffmpeg supports any.  
> **username_8**: CorePNG is able to create P frames also. Usually jpeg is not a lossless compression, and I doubt mjpeg can create P frames. I agree I do not answer the question as it is asked, but I give a solution to have a lossless video with ffmpeg.  

---

### Answer by username_2 on 2015-01-15. Score: 5

To expand on LordNeckbeard's answer, yes, just mux the JPEG data into an MJPEG video stream.  That will be the smallest representation of the exact sequence of output images, even though MJPEG is a terribly inefficient codec by today's standards.  (no temporal redundancy, and not even any intra prediction.
You can make a variable-framerate MJPEG video to take advantage of the duplicate images in your input.
ffmpeg -framerate 30 -i input%03d.jpg -vf mpdecimate -codec copy output.mkv  # doesn't work.

Hrm, this isn't going to work, since mpdecimate won't work on compressed data, and we can't let ffmpeg decode and then re-jpeg the image data without loss and CPU cost.
Maybe if you replaced duplicate jpg source files with empty files with that sequence number, or something?
Since this question isn't even recent, I'm not going to take the time to figure out how to do it unless someone replies to ask how.  But since MJPEG can go into an mkv container, I'm sure it's possible to have a file that doesn't duplicate the jpeg data for repeated frames, but instead just doesn't have an output frame to decode until the sequence of duplicates is over.
Oh here's an idea:
ffmpeg -framerate blah -input blah -vf mpdecimate -f mkvtimestamp_v2 mpdecimate.timestamps

Then remove (or move aside) all the jpegs for frames that mpdecimate wants to drop (probably it has some logging options?  Or -vf showinfo, and parse that, and move or hardlink only the frames that show up in its output, leaving behind the dropped JPEGs?).  mux that to a MJPEG.mkv, then do something with mkvmerge to replace the frame timestamps in that with the timestamps from mpdecimate.timestamps.
If you were xcoding, instead of just muxing jpeg data to MJPEG, this would be MUCH easier, since you'd just use my first command with mpdecimate and any codec other than copy, and it would Just Work(tm).
I haven't tried any of this, since this was an old question.  Also the reason I haven't filled in the gaps of how to actually filter your directory of jpegs based on mpdecimate output, or how to actually use the timestamp stream.


---

