Closed tomerarnon closed 7 years ago
Did you initialize panzoom
? (See the readme.)
Edit: it definitely is in the readme.
Another edit: using getgc(c)
like in the example yields the error
UndefVarError: getgc not defined in include_string(::String, ::String) at loading.jl:441 in include_string(::String, ::String, ::Int64) at eval.jl:30 in include_string(::Module, ::String, ::String, ::Int64, ::Vararg{Int64,N}) at eval.jl:34 in (::Atom.##53#56{String,Int64,String})() at eval.jl:50 in withpath(::Atom.##53#56{String,Int64,String}, ::String) at utils.jl:30 in withpath(::Function, ::String) at eval.jl:38 in macro expansion at eval.jl:49 [inlined] in (::Atom.##52#55{Dict{String,Any}})() at task.jl:60
and guidata[c, :xview] on it's own (outside of draw method) yields a similar error.
Original message: I didn't notice that in the README (just skimmed through again to make sure; I don't think it's in there) but I remember seeing it in your video. Doing so prevents the crash but also doesn't load copy the image into the canvas (black canvas appears).
For reference, this is what I am now doing:
A = Images.load(filepath)
panzoom(c)
@guarded draw(c) do widget
xview = guidata[widget, :xview]
println(xview)
copy!(widget, A)
end
Did you showall(win)
? That might solve the getgc
crashes.
Yes, at the end.
Try using Graphics
.
Once we get you up and running, would you mind submitting a pull request to improve the README? It's easier for you to know what's confusing than it is for me.
Using Graphics doesn't seem to correct the issue. Introducing getgc(c) produces the following error message:
ERROR: LoadError: UndefRefError: access to undefined reference
in getgc(::Gtk.GtkCanvas) at C:\Users\Tomer\.julia\v0.5\Gtk\src\cairo.jl:114
in include_from_node1(::String) at .\loading.jl:488
I've also tried updating the relevant packages in case that was the issue (it wasn't).
A window still appears after the error message, but it is empty. No complete crashes though.
I'd be happy to submit a pull request once this is sorted out.
That error means you're calling getgc
before the canvas is fully initialized. Safest if you put it inside the draw
function so you know it won't be called before the canvas is ready.
Maybe something like this?
using Gtk.ShortNames, Images, GtkUtilities, TestImages, Graphics
win = Window("image")
c = Canvas()
push!(win, c)
A = testimage("lighthouse")
zr = map(x->(first(x),last(x)), indices(A))
panzoom(c, zr[2], zr[1])
panzoom_mouse(c)
@guarded draw(c) do widget
set_coords(getgc(c), BoundingBox(0, width(c), 0, height(c)), BoundingBox(zr[2][1], zr[2][2], zr[1][1], zr[1][2]))
xview, yview = guidata[c, :xview], guidata[c, :yview]
xv = round(Int, xview.min):round(Int, xview.max)
yv = round(Int, yview.min):round(Int, yview.max)
copy!(widget, view(A, yv, xv))
end
showall(win)
See also the demos
folder.
Copy-pasting your code, it worked perfectly. Thanks!
Still not sure exactly what's going on, but I can probably replicate it for my application. I'll go through line by line with the documentation to figure out exactly what (voodoo) you're doing to get this to work, and once I figure it out, I'll consider how to amend the readme to be easily accessible for simple image manipulation like this.
Some of the mystery might diminish if you check out how Gtk defines draw
: https://github.com/JuliaGraphics/Gtk.jl/blob/00b7178d81e534e869f9169cf8e550f188a84b1b/src/cairo.jl#L74-L87. You can see how the getgc
calls are "protected" inside the draw function.
Do you mean that getgc
is protected by being run only if theif widget.is_realized && widget.is_sized
requirement is met?
I think the greatest source of confusion for me was/is coming from not completely understanding what set_coords()
did in this context, and why/how it was necessary. While I'm still not entirely sure, after going back to read its documentation at Cairo.jl
, my guess is that running it is required in order to use the ::xview (etc.)
functionality of guidata
. Is that correct?
I've commented and formatted the code you sent me to be (in my opinion) a bit more newbie friendly. Assuming everything is accurate and adequately explained, it could be a useful inclusion along with the julia_gui
demo, since it deals directly with images.
# example code for image manipulation using GtkUtilties
using Gtk.ShortNames, Images, GtkUtilities, Graphics, TestImages
A = testimage("lighthouse")
win = Window("image") # Create Window
c = Canvas() # Create Canvas
push!(win, c) # Place Canvas in Window
yx_ranges = map(x->(first(x),last(x)), indices(A)) # returns: yx_ranges = ((min-Y, max-Y), (min-X, max-X)). Note that y is first, since it refers to the rows of A
panzoom(c, yx_ranges[2], yx_ranges[1]) # Initialize panzoom *before* draw method, with arguments for x-y ranges.
panzoom_mouse(c) # Initialize mouse functions for panning/zooming
@guarded draw(c) do widget
set_coords( getgc(widget), # running set_coords is required to "set up" guidata[]. See Graphics.jl for more info on set_coords
BoundingBox(0,width(widget), # BoundingBox describing total viewable area in canvas
0,height(widget)), #
BoundingBox(yx_ranges[2][1], yx_ranges[2][2], # BoundingBox describing total image size
yx_ranges[1][1], yx_ranges[1][2]) ) #
xview, yview = guidata[widget, :xview], guidata[widget, :yview] # see readme for info on guidata[]
xv = round(Int, xview.min):round(Int, xview.max) #
yv = round(Int, yview.min):round(Int, yview.max) #
region_of_interest = view(A, yv, xv) # select subset of A according to the indices yv and xv
copy!(widget, region_of_interest) # copy the region of interest into c (widget)
end
showall(win)
I think the greatest source of confusion for me was/is coming from not completely understanding what set_coords() did in this context, and why/how it was necessary. While I'm still not entirely sure, after going back to read its documentation at Cairo.jl, my guess is that running it is required in order to use the ::xview (etc.) functionality of guidata. Is that correct?
It means that two-level zooming works properly: once you've zoomed in, the canvas coordinates become equal to the zoom region, so if you draw another rubber band then that becomes an adjustment relative to the first rubber band, not relative to the original full-image coordinates.
Aha! That makes a lot of sense.
Such double zooming is giving me a problem though. Rather than zooming in a second time, mouse-selection will bring me to somewhere else. It appears that the region it's bringing me to is as though the selection is relative to the unzoomed image. This is equally true using the ctrl-scroll method as well.
I've looked again at the julia_gui
example, and this problem only occurs in these image-loading scenarios. Any thoughts as to why?
I like it! Would be great to have this. Do you want to contribute it directly, or should I?
Ah, browser refresh delay hit me here. I'm not immediately sure why double-zooming isn't working. There's a chance I'm getting confused between device coordinates and user coordinates somewhere.
If you're adventurous, a whole new approach is brewing in https://github.com/JuliaGizmos/GtkReactive.jl/pull/2.
To be honest, I've been using git for about two weeks and still don't know exactly what I'm doing, so you might just have to do it yourself for that reason.
Maybe set_coords should take xview,yvew information instead of xvewlimits, yviewlimits? I'll give that a shot in a moment.
Just did... something? If it's what I intended then it's a pull request for a new demo file.
git is definitely a barrier. Nice job figuring it out!
Hi, At the moment I am using Gtk to build a gui, and would like to add GtkUtilities for its added interactivity functions. I'm running into issues whenever I try to incorporate anything from GtkUtilities, however.
A very simple draw function (like below) works fine.
Adding, for example,
guidata[c, :xview]
into the draw function in any form, crashes julia. E.g.:breaks the code. Since
guidata
is critical for panzoom and other operations, I'm not able to use GtkUtilities the way I would like/it was meant to be used. Is there something I'm obviously doing wrong here? I've tried following the julia_gui example as well as @timholy's youtube tutorial from a couple of years back about how to use panzoom, and haven't been able to improve my results.