# Displaying an image from a matrix using Gtk4

**URL:** <https://discourse.julialang.org/t/displaying-an-image-from-a-matrix-using-gtk4/104748>\
**Category:** Visualization\
**Created:** [October 9, 2023, 11:24am UTC](https://discourse.julialang.org/t/displaying-an-image-from-a-matrix-using-gtk4/104748 "2023-10-09T11:24:09Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![xor0110](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/xor0110/32/7926_2.png) [@xor0110](https://discourse.julialang.org/u/xor0110)\
**Post date:** [October 9, 2023, 11:24am UTC](https://discourse.julialang.org/t/displaying-an-image-from-a-matrix-using-gtk4/104748/1 "2023-10-09T11:24:09Z")

</div>

I want to display an image using Gtk, and be able to change the pixels later. I love ImageView and Makie, but I’m trying to do something as simple and low-level as possibel.

There are a couple of examples in the forum using Gtk (3):

> [@Unknown memory allocation when displaying pixels in Gtk.jl](https://discourse.julialang.org/t/unknown-memory-allocation-when-displaying-pixels-in-gtk-jl/82566):
>
> Hi all! I have some memory allocation I don’t understand when using Gtk, and hoping for some advice. I’ve built an application to display and tweak (many) scientifically computed 2kx2k images, and they are displayed through Gtk. In the process of optimizing it (using @time), I’ve notice some memory allocations I can’t understand. Below is a minimum working example. Is there a way I can avoid these allocations? Perhaps I should I be using something different than a GtkCanvas? A…

> [@Display an RGB array with Gtk.jl](https://discourse.julialang.org/t/display-an-rgb-array-with-gtk-jl/46506/2):
>
> You can check GtkReactive, if you don’t need the interactivity I think you just need to copy the image on a canva in the draw signal. [https://juliagizmos.github.io/GtkReactive.jl/stable/zoom\_pan.html](https://juliagizmos.github.io/GtkReactive.jl/stable/zoom_pan.html)

I was trying to use Gtk4, but apparently there have been changes in how you’re suppose to do that. Would anyone have and up-to-date example?

---

<div class="post-metadata">

**Author:** ![jwahlstrand](https://avatars.discourse-cdn.com/v4/letter/j/bcef8e/32.png) [@jwahlstrand](https://discourse.julialang.org/u/jwahlstrand)\
**Post date:** [October 9, 2023, 3:44pm UTC](https://discourse.julialang.org/t/displaying-an-image-from-a-matrix-using-gtk4/104748/2 "2023-10-09T15:44:42Z")

</div>

Here’s an updated version of the second example:

```julia
using Gtk4, Gtk4.GdkPixbufLib

function rgb_to_pixbuf(img_rgb::Array{UInt32})
    (x, y) = size(img_rgb)[1:2]
    data = Array{GdkPixbufLib.RGB}(undef, x, y)
    for i in 1:x, j in 1:y
        data[i, j] = GdkPixbufLib.RGB((img_rgb[i, j, 1]),
                                      (img_rgb[i, j, 2]),
                                      (img_rgb[i, j, 3]))
    end
    GdkPixbuf(data)
end

# creating a red test array
img_rgb = Array{UInt32}(undef, 300, 300, 3)
img_rgb[:,:,1] .= 255
img_rgb[:,:,2] .= 0
img_rgb[:,:,3] .= 0

win = GtkWindow("Matrix", 900, 700) 
pb = rgb_to_pixbuf(img_rgb)
pic = GtkPicture(pb)
win[] = pic

```

To change the image, you can alter the matrix, create a new pixbuf, then call `Gtk4.pixbuf(pic, pb)`. There might be a way to alter the pixbuf data directly, but this should work.

---

<div class="post-metadata">

**Author:** ![xor0110](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/xor0110/32/7926_2.png) [@xor0110](https://discourse.julialang.org/u/xor0110)\
**Post date:** [October 10, 2023, 7:55am UTC](https://discourse.julialang.org/t/displaying-an-image-from-a-matrix-using-gtk4/104748/3 "2023-10-10T07:55:14Z")

</div>

Thanks a lot! I am interested indeed in altering the pixbuf directly, I’m concerned about minimizing memory allocations and copying… Would there be a Gtk based safe way to do it, or maybe we need to define a view using the Pixbuf attributes?

---

<div class="post-metadata">

**Author:** ![jwahlstrand](https://avatars.discourse-cdn.com/v4/letter/j/bcef8e/32.png) [@jwahlstrand](https://discourse.julialang.org/u/jwahlstrand)\
**Post date:** [October 10, 2023, 12:00pm UTC](https://discourse.julialang.org/t/displaying-an-image-from-a-matrix-using-gtk4/104748/4 "2023-10-10T12:00:35Z")

</div>

It turns out you can just modify the pixbuf data in place. The code below updates the image without allocating (in Julia):

```julia
using Gtk4, Gtk4.GdkPixbufLib

module MatrixFiller
    using Gtk4.GdkPixbufLib
    function incr_green!(pb_rgb)
        for j in eachindex(pb_rgb)
            pb_rgb[j] = GdkPixbufLib.RGB(pb_rgb[j].r,pb_rgb[j].g+32,pb_rgb[j].b)
        end
    end
end

function rgb_to_pixbufrgb(img_rgb::Array{UInt32})
    (x, y) = size(img_rgb)[1:2]
    data = Array{GdkPixbufLib.RGB}(undef, x, y)
    for i in 1:x, j in 1:y
        data[i, j] = GdkPixbufLib.RGB((img_rgb[i, j, 1]),
                                      (img_rgb[i, j, 2]),
                                      (img_rgb[i, j, 3]))
    end
    data
end

# creating a red test array
img_rgb = Array{UInt32}(undef, 300, 300, 3)
img_rgb[:,:,1] .= 255
img_rgb[:,:,2] .= 0
img_rgb[:,:,3] .= 0

win = GtkWindow("Matrix", 900, 700) 
const pb_rgb = rgb_to_pixbufrgb(img_rgb)
const pb = GdkPixbuf(pb_rgb) # this pixbuf uses `pb_rgb` as its data
pic = GtkPicture(pb)
win[] = pic

MatrixFiller.incr_green!(pb_rgb) # increment the green channel -- no allocations after first call
Gtk4.pixbuf(pic,pb) # refresh the picture -- no allocations after first call

```

---

<div class="post-metadata">

**Author:** ![Hossein\_Haghi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/hossein_haghi/32/9413_2.png) [@Hossein\_Haghi](https://discourse.julialang.org/u/Hossein_Haghi)\
**Post date:** [February 16, 2024, 9:22pm UTC](https://discourse.julialang.org/t/displaying-an-image-from-a-matrix-using-gtk4/104748/5 "2024-02-16T21:22:31Z")

</div>

I am trying to do something similar with matrices that look something like this

img = rand(UInt8, 256, 256)

Can you please point me in the right direction?

---

<div class="post-metadata">

**Author:** ![xor0110](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/xor0110/32/7926_2.png) [@xor0110](https://discourse.julialang.org/u/xor0110)\
**Post date:** [February 26, 2024, 2:47pm UTC](https://discourse.julialang.org/t/displaying-an-image-from-a-matrix-using-gtk4/104748/6 "2024-02-26T14:47:42Z")

</div>

Have you tried with RGB first?.. Not sure there will be a simple way using grayscale, it must become RGB at some point so the data goes to the monitor
