Resetting the canvas within Cairo.jl and Gtk.jl for an image selection viewing gui

#1

I have here a MWE for what is a Gtk window (Gkt.jl) that uses Cairo to draw on the canvas some png image files. There is a ‘button’ that changes a counter for the selection of which image is drawn, but the images are overlapping each other rather than starting on a ‘blank canvas’ or resetting it in some way.

using Gtk
using Cairo

global drawInt = 1

function drawSys(widget)
    ctx = Gtk.getgc(widget)
    global drawInt
    
    c = CairoRGBSurface(400,20);
    cr = CairoContext(c);

    set_source_rgb(cr,0.8,0.8,0.8);    # light gray
    rectangle(cr,0.0,0.0,800.0,650.0); # background
    fill(cr);

    #save(cr);
    if(drawInt%2 == 0)
        image = read_from_png("dog.png")
    else
        image = read_from_png("pets.png")
    end
    
    set_source_surface(ctx, image, 0, 0)
    paint(ctx)
    #fill(ctx)    
end
function drawUpdater1()   
    global drawInt
    drawInt += 1
    
end
function on_button_clicked(w)
    drawUpdater1()
    println("The button has been clicked and replot")
    ctx = Gtk.getgc(canvas)
    draw(canvas)
    
end
win = Gtk.Window("Gtk") |> (bx = Gtk.Box(:v))
canvas = Gtk.Canvas(800, 650)
push!(bx, canvas)
canvas.draw = drawSys#what is registered in every window event
bt = Gtk.Button("ok")
push!(bx, bt)
signal_connect(on_button_clicked, bt, "clicked")

Gtk.showall(win)

How can this be modified so that, the images start on a fresh canvas so that the previous image is not seen/visible? How can the images be resized so that they fit into a preset dimension size, or fill up the designated ‘canvas’ widet?

#2

For the ‘fresh’ canvas you need to fill the area with your background color.
For scaling the image you need to apply a coordinate scaling before painting (Cairo.scale(ctx, xscale, yscale).
(btw: it’s not clear what you want to do with c and cr in the example)

1 Like
#3

I included the line for the scaling Cairo.scale(ctx,xscale,yscale) but for some reason it looks like the scaling is persistent. In that each subsequent image becomes scaled from the previous (so less than 1 eventually goes to 0)

I copied the code for ‘c’ and ‘cr’ from https://github.com/JuliaGraphics/Cairo.jl/blob/master/samples/sample_image.jl

is there a simple area filling statement? (for a particular color?)

#4

(I’m using cairo for ~10 years, so i’m not thinking about the basic concepts anymore …)

If you apply scaling you do a coordinate transformation for the context and this is persistent. You can use save/restore pairs for pushing the current state of the context on a stack and get it back.

Simply do a rectangle and fill. (iirc this rectangle is defined in some cases of gtk rendering, like redrawing, you’d need to check gtk documentation).

1 Like
#5

Thanks, do you think that there is a hard limit on this approach and use for the frame updates to about 24fps?

and the Gtk.Canvas dimension settings seem to ‘crop’ the images… is it best to then do the scaling from the Cairo scale function each time there is the painting/drawing?

As well, I get a Gtk-WARNING **: drawing failure for widget 'GtkBox': out of memory from the use of Cairo.scale(ctx,.5,.5) on repeat, although I redraw the rectangles and images from .png images

#6

Well, there is not a hard limit, but depending on what you actually paint/render 50ms might not be enough time. But bitmap/image painting is rather efficient - you might need to look at filtering/antialiasing settings.

There is inherent cropping/clipping as the Canvas itself has a size. I’d recommend to calculate the scaling factors, so the image is scaled to canvas width (or height depending on the orienation).

Out of memories can happen quite fast if you use a lot of intermediate images (read_from_png) and GC has not started.

1 Like
#7

From using cairo_scale(ctx,.5,.5) the image on each button push is half of half of half… on repeat. How can this be applied to the first time and from the original image upon iterations? Why does it cycle upon the previous scaled image it produced?

The link to the doc in the repo https://github.com/JuliaGraphics/Cairo.jl seems to be not be working, is there a doc file for the functions that can be used and some explanations?

#8

For documentation:
Cairo.jl follows the libcairo API, so you can use https://www.cairographics.org/manual/ and https://www.cairographics.org/tutorial/
Cairo.jl also includes Examples in https://github.com/JuliaGraphics/Cairo.jl/blob/master/samples/Samples.md

1 Like