# Multithread image processing with Cairo.jl / Luxor.jl possible?

**URL:** <https://discourse.julialang.org/t/multithread-image-processing-with-cairo-jl-luxor-jl-possible/55920>\
**Category:** General Usage\
**Created:** [February 24, 2021, 8:40am UTC](https://discourse.julialang.org/t/multithread-image-processing-with-cairo-jl-luxor-jl-possible/55920 "2021-02-24T08:40:10Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Fred](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fred/32/14175_2.png) [@Fred](https://discourse.julialang.org/u/Fred)\
**Post date:** [February 24, 2021, 8:40am UTC](https://discourse.julialang.org/t/multithread-image-processing-with-cairo-jl-luxor-jl-possible/55920/1 "2021-02-24T08:40:10Z")

</div>

Hi,  
This is a toy program that draw circles on the Julia logo. It woks sequentially but when I try to do parallel image processing I have this error with Julia 1.5.3 up to date.

`julia: cairo-surface.c :2092 : _cairo_surface_release_source_image: l'assertion « !surface->finished » a échoué.`

Is it because the cairo library cannot be used by multiple threads or am I doing something wrong ?  
Thanks !

file main.jl

```julia
using Luxor

include("proc.jl")

Threads.@threads for i in 1:10
#for i in 1:10
    process(i)
end

```

file proc.jl

```julia
function process(i)
    image = readpng("Julia_Logo.png")
    println(i, " image read")

    w = image.width
    h = image.height

    # file output
    fname = "image$i.png"

    Drawing(w, h, fname)
    
    placeimage(image, 0, 0)

    setcolor((255,0,0,0.3))

    for x in 1:50
        x1 = rand()*w
        y1 = rand()*h
        circle(Point(x1, y1), 12, :fill) # draw a circle on the image
    end
    finish()
end

```

---

<div class="post-metadata">

**Author:** ![cormullion](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cormullion/32/49131_2.png) [@cormullion](https://discourse.julialang.org/u/cormullion)\
**Post date:** [February 24, 2021, 11:14am UTC](https://discourse.julialang.org/t/multithread-image-processing-with-cairo-jl-luxor-jl-possible/55920/2 "2021-02-24T11:14:20Z")

</div>

Hi! It’s a question best directed at Cairo.jl, because Luxor is a just a sugary wrapper for raw Cairo functionality…🍦😅

---

<div class="post-metadata">

**Author:** ![Fred](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fred/32/14175_2.png) [@Fred](https://discourse.julialang.org/u/Fred)\
**Post date:** [February 24, 2021, 11:17am UTC](https://discourse.julialang.org/t/multithread-image-processing-with-cairo-jl-luxor-jl-possible/55920/3 "2021-02-24T11:17:28Z")

</div>

@cormullion I changed the title to mention Cairo.jl. Thank you for writing Luxor.jl, it is very cool 😉

---

<div class="post-metadata">

**Author:** ![Fred](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fred/32/14175_2.png) [@Fred](https://discourse.julialang.org/u/Fred)\
**Post date:** [February 27, 2021, 8:03am UTC](https://discourse.julialang.org/t/multithread-image-processing-with-cairo-jl-luxor-jl-possible/55920/4 "2021-02-27T08:03:02Z")

</div>

I tried to put a lock() at the final step of image processing :

```julia
function process(i)
    image = readpng("Julia_Logo.png")
    println(i, " image read")

    w = image.width
    h = image.height

    # file output
    fname = "results/image$i.png"

    Drawing(w, h, fname)
    
    placeimage(image, 0, 0)

    setcolor((255,0,0,0.3))

    for x in 1:50
        x1 = rand()*w
        y1 = rand()*h
        circle(Point(x1, y1), 5, :fill) # draw a circle on the image
    end
    begin
        lock(a)
        try
            finish(a)
        finally
            unlock(a)
        end
    end
end

```

there is a little improvement, some images are processed in parallel, but there is still a race problem related to the library Cairo

```julia
$ julia main.jl 
1 image read
9 image read
7 image read
4 image read
julia: cairo-path-fixed.c :392 : _cairo_path_fixed_drop_line_to: l'assertion « _cairo_path_fixed_last_op (path) == CAIRO_PATH_OP_LINE_TO » a échoué.

```

---

<div class="post-metadata">

**Author:** ![lobingera](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lobingera/32/211_2.png) [@lobingera](https://discourse.julialang.org/u/lobingera)\
**Post date:** [February 27, 2021, 11:45am UTC](https://discourse.julialang.org/t/multithread-image-processing-with-cairo-jl-luxor-jl-possible/55920/5 "2021-02-27T11:45:01Z")

</div>

I don’t think libcairo is working multithreading and Cairo.jl has no idea about multithreading either ([Completely rework pointer management. · Issue #320 · JuliaGraphics/Cairo.jl · GitHub](https://github.com/JuliaGraphics/Cairo.jl/issues/320) shows some work on pointer management and GC needed).

If you really need to work on drawing in threads, i’d do a surface per thread and combine them after finishing.

---

<div class="post-metadata">

**Author:** ![Fred](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fred/32/14175_2.png) [@Fred](https://discourse.julialang.org/u/Fred)\
**Post date:** [February 27, 2021, 12:00pm UTC](https://discourse.julialang.org/t/multithread-image-processing-with-cairo-jl-luxor-jl-possible/55920/6 "2021-02-27T12:00:35Z")

</div>

@lobingera thanks for your explanation, it is important for me to know that the limitation comes from the library and not a mistake in my code 🙂
