# A way to capture screenshots with Julia programatically

**URL:** <https://discourse.julialang.org/t/a-way-to-capture-screenshots-with-julia-programatically/57666>\
**Category:** General Usage\
**Tags:** io\
**Created:** [March 21, 2021, 7:27pm UTC](https://discourse.julialang.org/t/a-way-to-capture-screenshots-with-julia-programatically/57666 "2021-03-21T19:27:56Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![sefffal](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sefffal/32/23640_2.png) [@sefffal](https://discourse.julialang.org/u/sefffal)\
**Post date:** [March 21, 2021, 7:27pm UTC](https://discourse.julialang.org/t/a-way-to-capture-screenshots-with-julia-programatically/57666/1 "2021-03-21T19:27:56Z")

</div>

Today I found a simple way to capture a screenshot of your desktop using Julia and thought I would share.

I guess it is a hidden feature of the [ImageMagick.jl](https://github.com/JuliaIO/ImageMagick.jl) package.

Just run

```julia
using ImageMagick
screenshot = ImageMagick.load("screenshot:")

```

If you also load the Images package it will display as any other image would. Or you can also use FileIO to easily save it to a PNG or other format.

I tested this on Windows 10 and it works quite well. It has a few hiccups with high DPI screens.  
If you have multiple monitors, you instead get a 3D array where the third axis selects the screen.

From some quick searching, it’s possible than “screenshot:” should be replaced with “x:root” on linux but I don’t have a linux install to test with.

---

<div class="post-metadata">

**Author:** ![Skoffer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/skoffer/32/378_2.png) [@Skoffer](https://discourse.julialang.org/u/Skoffer)\
**Post date:** [March 21, 2021, 7:41pm UTC](https://discourse.julialang.org/t/a-way-to-capture-screenshots-with-julia-programatically/57666/2 "2021-03-21T19:41:14Z")

</div>

Hmm, it’s not working on my ubuntu installation

```julia
julia> screenshot = ImageMagick.load("x:root")
ERROR: UnableToOpenBlob `x:root': No such file or directory @ error/blob.c/OpenBlob/2873
Stacktrace:
 [1] error(s::String)
   @ Base ./error.jl:33
 [2] error(wand::MagickWand)
   @ ImageMagick ~/.julia/packages/ImageMagick/mOSDB/src/libmagickwand.jl:187
 [3] readimage
   @ ~/.julia/packages/ImageMagick/mOSDB/src/libmagickwand.jl:274 [inlined]
 [4] load_(file::String, permute_horizontal::Bool; ImageType::Type, extraprop::String, extraprop
ertynames::Nothing, view::Bool)
   @ ImageMagick ~/.julia/packages/ImageMagick/mOSDB/src/ImageMagick.jl:146
 [5] load_
   @ ~/.julia/packages/ImageMagick/mOSDB/src/ImageMagick.jl:139 [inlined]
 [6] #load#30
   @ ~/.julia/packages/ImageMagick/mOSDB/src/ImageMagick.jl:126 [inlined]
 [7] load(::String)
   @ ImageMagick ~/.julia/packages/ImageMagick/mOSDB/src/ImageMagick.jl:126
 [8] top-level scope
   @ REPL[9]:1

```

---

<div class="post-metadata">

**Author:** ![sefffal](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sefffal/32/23640_2.png) [@sefffal](https://discourse.julialang.org/u/sefffal)\
**Post date:** [March 21, 2021, 7:50pm UTC](https://discourse.julialang.org/t/a-way-to-capture-screenshots-with-julia-programatically/57666/3 "2021-03-21T19:50:34Z")

</div>

That annoying! And I take it `screenshot:` didn’t work either?

---

<div class="post-metadata">

**Author:** ![Skoffer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/skoffer/32/378_2.png) [@Skoffer](https://discourse.julialang.org/u/Skoffer)\
**Post date:** [March 21, 2021, 7:52pm UTC](https://discourse.julialang.org/t/a-way-to-capture-screenshots-with-julia-programatically/57666/4 "2021-03-21T19:52:02Z")

</div>

No luck

```julia
julia> screenshot = ImageMagick.load("screenshot:")
ERROR:
Stacktrace:
 [1] error(s::String)
   @ Base ./error.jl:33
 [2] error(wand::MagickWand)
   @ ImageMagick ~/.julia/packages/ImageMagick/mOSDB/src/libmagickwand.jl:187
 [3] readimage
   @ ~/.julia/packages/ImageMagick/mOSDB/src/libmagickwand.jl:274 [inlined]
 [4] load_(file::String, permute_horizontal::Bool; ImageType::Type, extraprop::String, extraprop
ertynames::Nothing, view::Bool)
   @ ImageMagick ~/.julia/packages/ImageMagick/mOSDB/src/ImageMagick.jl:146
 [5] load_
   @ ~/.julia/packages/ImageMagick/mOSDB/src/ImageMagick.jl:139 [inlined]
 [6] #load#30
   @ ~/.julia/packages/ImageMagick/mOSDB/src/ImageMagick.jl:126 [inlined]
 [7] load(::String)
   @ ImageMagick ~/.julia/packages/ImageMagick/mOSDB/src/ImageMagick.jl:126
 [8] top-level scope
   @ REPL[13]:1

```

---

<div class="post-metadata">

**Author:** ![sefffal](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sefffal/32/23640_2.png) [@sefffal](https://discourse.julialang.org/u/sefffal)\
**Post date:** [March 21, 2021, 7:59pm UTC](https://discourse.julialang.org/t/a-way-to-capture-screenshots-with-julia-programatically/57666/5 "2021-03-21T19:59:03Z")

</div>

That’s too bad! I was hoping this would work cross-platform. Looking through the Image Magick C code there’s both a linux and Windows code path. Not sure why one is not supported.

Oh well, hopefully it can still be useful for Windows users.

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [March 21, 2021, 8:07pm UTC](https://discourse.julialang.org/t/a-way-to-capture-screenshots-with-julia-programatically/57666/6 "2021-03-21T20:07:08Z")

</div>

You could use Python’s `PIL.ImageGrab.grab()` via PyCall.

Looking at the [source code](https://github.com/python-pillow/Pillow/blob/master/src/PIL/ImageGrab.py), it seems feasible to put together a Julia package with similar functionality.

(Note that the [Win32 code is here in C](https://github.com/python-pillow/Pillow/blob/d374015504df2c7f0316154deade1bc1fa5075df/src/display.c#L318-L422), and looks relatively complicated but could be implemented via `ccall`. The [X11 code is here](https://github.com/python-pillow/Pillow/blob/d374015504df2c7f0316154deade1bc1fa5075df/src/display.c#L892-L980). I wonder if there is a simpler way to do it, though?)

---

<div class="post-metadata">

**Author:** ![sefffal](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sefffal/32/23640_2.png) [@sefffal](https://discourse.julialang.org/u/sefffal)\
**Post date:** [March 21, 2021, 8:16pm UTC](https://discourse.julialang.org/t/a-way-to-capture-screenshots-with-julia-programatically/57666/7 "2021-03-21T20:16:08Z")

</div>

Thanks for the pointer @stevengj. The `grabclipboard` function could really come in handy too if it were ported.

---

<div class="post-metadata">

**Author:** ![KingBoomie](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kingboomie/32/29760_2.png) [@KingBoomie](https://discourse.julialang.org/u/KingBoomie)\
**Post date:** [October 7, 2021, 6:47pm UTC](https://discourse.julialang.org/t/a-way-to-capture-screenshots-with-julia-programatically/57666/8 "2021-10-07T18:47:36Z")

</div>

On ubuntu 20, calling imagemagick from the command line worked for me as a workaround:

```julia
using FileIO
using ImageIO

cmd = `import -window root png:-`
io = read(cmd)
img = load(IOBuffer(io))

```

---

<div class="post-metadata">

**Author:** ![Ashwani\_Rathee](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ashwani_rathee/32/49551_2.png) [@Ashwani\_Rathee](https://discourse.julialang.org/u/Ashwani_Rathee)\
**Post date:** [January 25, 2022, 1:44pm UTC](https://discourse.julialang.org/t/a-way-to-capture-screenshots-with-julia-programatically/57666/9 "2022-01-25T13:44:30Z")

</div>

I think this would helpful for linux people with the screen shots with framerate for bgra ones over 90 fps, rgb around 2fps and gray also 2fps(I could use help how to fix that) and offset of originx, origin y are available and width and height of screenshot are definable:

[https://github.com/ashwani-rathee/GrabScreen.jl](https://github.com/ashwani-rathee/GrabScreen.jl)

I am still working on the performance issues with RGB and GRAY, X11 isn’t most flexible.

Issue is that X11 returns me with vector of uint8 with 4 bits for pixel, for let’s 100\*100, it would be 40000 values, for BGRA ones I directly do

```julia
    res = reinterpret(BGRA{N0f8}, res)
    res = reshape(res , Width, Height)
    res = res'

```

Which is pretty fast but then when I have to something similiar for RGB, Gray it becomes a issue  
RGB.(res), Gray.(res) are quite slow for realtime purposes and I am not able to think of faster solution atm.
