# Creating a video from a stack of Images

**URL:** <https://discourse.julialang.org/t/creating-a-video-from-a-stack-of-images/646>\
**Category:** Signal and Image Processing\
**Created:** [November 30, 2016, 4:28am UTC](https://discourse.julialang.org/t/creating-a-video-from-a-stack-of-images/646 "2016-11-30T04:28:11Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![vchuravy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/vchuravy/32/8_2.png) [@vchuravy](https://discourse.julialang.org/u/vchuravy)\
**Post date:** [November 30, 2016, 4:28am UTC](https://discourse.julialang.org/t/creating-a-video-from-a-stack-of-images/646/1 "2016-11-30T04:28:11Z")

</div>

[VideoIO.jl](https://github.com/kmsquire/VideoIO.jl) only seems to have the capabilities of reading in video with ffmpeg.  
I couldn’t find any options to create a Video so I was wondering if I am missing something.

I know @sdanisch is exporting to png files first and then uses ffmpeg to create a video. That is not really an option for me since my image data is quite large.

---

<div class="post-metadata">

**Author:** ![kevin.squire](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kevin.squire/32/62_2.png) [@kevin.squire](https://discourse.julialang.org/u/kevin.squire)\
**Post date:** [November 30, 2016, 6:42am UTC](https://discourse.julialang.org/t/creating-a-video-from-a-stack-of-images/646/2 "2016-11-30T06:42:04Z")

</div>

ffmpeg certainly has the capability to produce videos, and I had intended on adding it to [VideoIO.jl](https://github.com/kmsquire/VideoIO.jl) a long time ago, but it’s been challenging for me to make the time for that package recently. Pull requests are very welcome.

In the mean time, you might check to see if one of the [OpenCV.jl](https://github.com/JuliaOpenCV/OpenCV.jl) [implementations](https://github.com/maxruby/OpenCV.jl) implements video. I know that OpenCV supports it, but I don’t know if that functionality has been exposed in either package.

(I’m also not sure how easy it is to install either package, as neither is registered.)

Sorry not to be more helpful.

Cheers,  
Kevin

---

<div class="post-metadata">

**Author:** ![tknopp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tknopp/32/3569_2.png) [@tknopp](https://discourse.julialang.org/u/tknopp)\
**Post date:** [November 30, 2016, 7:52am UTC](https://discourse.julialang.org/t/creating-a-video-from-a-stack-of-images/646/3 "2016-11-30T07:52:47Z")

</div>

Hi, I now use Images.jl or actually ImageMagick.jl for this task which works pretty well. You just have to convert the data first to an RGB Image and then simply call save. But I think this just works for animated gifs, which are in my case pretty suitable.

---

<div class="post-metadata">

**Author:** ![jheinen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jheinen/32/2787_2.png) [@jheinen](https://discourse.julialang.org/u/jheinen)\
**Post date:** [November 30, 2016, 8:03am UTC](https://discourse.julialang.org/t/creating-a-video-from-a-stack-of-images/646/4 "2016-11-30T08:03:07Z")

</div>

`GR.jl` can produce videos on the fly. You can find some examples in [this](https://pgi-jcns.fz-juelich.de/pub/doc/SciPy_2016/html) talk (e.g. slides 10, 11). There’s also a backend for animated GIFs - but creating videos (with only 256 colors) is probably not what you want …

---

<div class="post-metadata">

**Author:** ![cstjean](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cstjean/32/1444_2.png) [@cstjean](https://discourse.julialang.org/u/cstjean)\
**Post date:** [November 30, 2016, 2:07pm UTC](https://discourse.julialang.org/t/creating-a-video-from-a-stack-of-images/646/5 "2016-11-30T14:07:18Z")

</div>

I looked around about a year ago, and the best I could do was to use [matplotlib.animation.FuncAnimation](http://matplotlib.org/api/animation_api.html#matplotlib.animation.FuncAnimation) via PyCall. I wouldn’t recommend it, but I can post my code if the other options don’t work for you.

---

<div class="post-metadata">

**Author:** ![vchuravy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/vchuravy/32/8_2.png) [@vchuravy](https://discourse.julialang.org/u/vchuravy)\
**Post date:** [December 6, 2016, 2:19am UTC](https://discourse.julialang.org/t/creating-a-video-from-a-stack-of-images/646/6 "2016-12-06T02:19:46Z")

</div>

Thank you all for the suggestions I solved my particular problem the following way

```julia
open(`ffmpeg -f rawvideo -pix_fmt gray -s:v 5120x5120 -r 70 -i pipe:0 test.mkv`, "w") do out
    for frame in video
        img = convert(Image{Gray{U8}}, frame)
        write(out, reinterpret(UInt8, data(img)))
    end
end

```

It is not terrible performant but it get’s the job done for now.

---

<div class="post-metadata">

**Author:** ![stillyslalom](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stillyslalom/32/45687_2.png) [@stillyslalom](https://discourse.julialang.org/u/stillyslalom)\
**Post date:** [May 7, 2018, 8:15am UTC](https://discourse.julialang.org/t/creating-a-video-from-a-stack-of-images/646/7 "2018-05-07T08:15:30Z")

</div>

This is great! I updated and generalized it a bit:

```julia
using Images

function writevideo(imgstack, filename; overwrite=true, framerate=30)
    # Input validation
    length(size(imgstack)) == 3 || error("input image must have three dimensions")
    if !(eltype(imgstack) <: Color)
        error("element type of input array is $(eltype(imgstack));
         needs to be RGB or Gray")
     end

    # Translate inputs to command line args
    ow = overwrite ? "-y" : ""
    w, h, nframes = size(imgstack)

    if eltype(imgstack) <: RGB
        open(`ffmpeg $ow -f rawvideo -pix_fmt rgb24 -s:v $(w)x$(h)
            -r $framerate -i pipe:0 -vf "transpose=0" $filename`, "w") do out
            for i = 1:nframes
                write(out, convert.(RGB24, imgstack[:,:,i]))
            end
        end
    else
        open(`ffmpeg $ow -f rawvideo -pix_fmt gray -s:v $(w)x$(h)
            -r $framerate -i pipe:0 -vf "transpose=0" $filename`, "w") do out
            for i = 1:nframes
                write(out, convert.(Gray{N0f8}, imgstack[:,:,i]))
            end
        end
    end
end

```

---

<div class="post-metadata">

**Author:** ![stillyslalom](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stillyslalom/32/45687_2.png) [@stillyslalom](https://discourse.julialang.org/u/stillyslalom)\
**Post date:** [May 7, 2018, 11:50pm UTC](https://discourse.julialang.org/t/creating-a-video-from-a-stack-of-images/646/8 "2018-05-07T23:50:55Z")

</div>

Further modified (after much head-bashing) to allow for near-universally-compatible output:

```julia
using Images

function writevideo(fname, imgstack::Array{<:Color,3};
                    overwrite=true, fps=30::UInt, options=``)
    ow = overwrite ? `-y` : `-n`
    h, w, nframes = size(imgstack)

    open(`ffmpeg
            -loglevel warning
            $ow
            -f rawvideo
            -pix_fmt rgb24
            -s:v $(h)x$(w)
            -r $fps
            -i pipe:0
            $options
            -vf "transpose=0"
            -pix_fmt yuv420p
            $fname`, "w") do out
        for i = 1:nframes
            write(out, convert.(RGB{N0f8}, clamp01.(imgstack[:,:,i])))
        end
    end
end

```

@kevin.squire: worth making a PR to VideoIO?

---

<div class="post-metadata">

**Author:** ![dehann](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dehann/32/2003_2.png) [@dehann](https://discourse.julialang.org/u/dehann)\
**Post date:** [August 23, 2020, 3:37pm UTC](https://discourse.julialang.org/t/creating-a-video-from-a-stack-of-images/646/9 "2020-08-23T15:37:02Z")

</div>

Hi All, this function is great (thanks!) – if there are no objections, I added the latest `writevideo` function (with minor changes/fixes) to a registered package here:  
[https://github.com/JuliaRobotics/Caesar.jl/blob/fce7ce982b96c40d39aa7771283ffbf132a533c5/src/images/images.jl#L13](https://github.com/JuliaRobotics/Caesar.jl/blob/fce7ce982b96c40d39aa7771283ffbf132a533c5/src/images/images.jl#L13)

Also a shout out to `Video4Linux.jl` which might be of use to folks:  
[https://github.com/Affie/Video4Linux.jl](https://github.com/Affie/Video4Linux.jl)

---

<div class="post-metadata">

**Author:** ![stillyslalom](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stillyslalom/32/45687_2.png) [@stillyslalom](https://discourse.julialang.org/u/stillyslalom)\
**Post date:** [August 23, 2020, 6:47pm UTC](https://discourse.julialang.org/t/creating-a-video-from-a-stack-of-images/646/10 "2020-08-23T18:47:54Z")

</div>

Have you tried [VideoIO.jl](https://juliaio.github.io/VideoIO.jl/latest/writing/)? If that works for your use case, it’ll be more robust & user-friendly to add that as a lazy-loaded dependency than requiring people to install FFMPEG themselves.

---

<div class="post-metadata">

**Author:** ![ianshmean](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ianshmean/32/216042_2.png) [@ianshmean](https://discourse.julialang.org/u/ianshmean)\
**Post date:** [August 25, 2020, 12:30am UTC](https://discourse.julialang.org/t/creating-a-video-from-a-stack-of-images/646/11 "2020-08-25T00:30:40Z")

</div>

There’s also [FFMPEG.jl](https://github.com/JuliaIO/FFMPEG.jl) if you didn’t want to switch to the convenience functions VideoIO provides.

---

<div class="post-metadata">

**Author:** ![dehann](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dehann/32/2003_2.png) [@dehann](https://discourse.julialang.org/u/dehann)\
**Post date:** [August 26, 2020, 12:51am UTC](https://discourse.julialang.org/t/creating-a-video-from-a-stack-of-images/646/12 "2020-08-26T00:51:07Z")

</div>

I haven’t tried VideoIO.jl recently but looks to be a good solution for writing videos thanks!
