Skip to content

Commit

Permalink
Merge pull request #114 from timholy/teh/indices
Browse files Browse the repository at this point in the history
Support display of non-1 arrays
  • Loading branch information
timholy authored Apr 17, 2017
2 parents 53965ae + 8c77a10 commit 0ad314c
Show file tree
Hide file tree
Showing 7 changed files with 47 additions and 32 deletions.
3 changes: 0 additions & 3 deletions src/ImageView.jl
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,4 @@ export # types
toplevel,
write_to_png

@deprecate view imshow
@deprecate viewlabeled imshowlabeled

end
6 changes: 3 additions & 3 deletions src/annotations.jl
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ type AnnotationLines{R<:Union{Real, Tuple{Real, Real}}, T}
coordinate_order::Vector{Int}

function AnnotationLines(lines::T, z, t, linecolor, linewidth, coord_order_str)
ord = sortperm(coord_order_str.data)
ord = sortperm(Vector{UInt8}(coord_order_str))
@assert coord_order_str[ord] == "xxyy"
new(lines, z, t, linecolor, linewidth, ord)
end
Expand Down Expand Up @@ -149,7 +149,7 @@ AnnotationLine(pt1::Tuple{Real,Real}, pt2::Tuple{Real,Real}; args...) =
AnnotationLine((pt1, pt2); args...)

function AnnotationLine(c1::Real, c2::Real, c3::Real, c4::Real; coord_order="xyxy", args...)
ord = sortperm(coord_order.data)
ord = sortperm(Vector{UInt8}(coord_order))
@assert coord_order[ord] == "xxyy"
(x1,x2,y1,y2) = [c1,c2,c3,c4][ord]
AnnotationLine((Float64(x1), Float64(y1)),
Expand All @@ -171,7 +171,7 @@ end

function AnnotationBox(c1::Real, c2::Real, c3::Real, c4::Real; z = NaN, t = NaN,
color=RGB(1,1,1), linewidth=1.0, coord_order="xyxy")
ord = sortperm(coord_order.data)
ord = sortperm(Vector{UInt8}(coord_order))
@assert coord_order[ord] == "xxyy"
(x1, x2, y1, y2) = [c1, c2, c3, c4][ord]
(x1, x2) = minmax(x1, x2)
Expand Down
57 changes: 35 additions & 22 deletions src/display.jl
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ type ImageCanvas

function ImageCanvas(fmt::Int32, props::Dict)
ps = get(props, :pixelspacing, nothing)
aspect_x_per_y = is(ps, nothing) ? nothing : ps[1]/ps[2]
aspect_x_per_y = ps == nothing ? nothing : ps[1]/ps[2]
if haskey(props, :render!)
render! = props[:render!]
else
Expand Down Expand Up @@ -76,7 +76,7 @@ parent(imgc::ImageCanvas) = Tk.parent(imgc.c)
toplevel(imgc::ImageCanvas) = Tk.toplevel(canvas(imgc))

function setbb!(imgc::ImageCanvas, w, h)
if !is(imgc.aspect_x_per_y, nothing)
if imgc.aspect_x_per_y != nothing
wc = width(imgc.c)
hc = height(imgc.c)
sx = min(wc/w, imgc.aspect_x_per_y*hc/h)
Expand Down Expand Up @@ -115,9 +115,11 @@ end
import Base.getindex
function getindex(img2::ImageSlice2d, x::Real, y::Real)
P = img2.imorig
indexes = RangeIndex[1:size(P,d) for d = 1:ndims(P)]
indexes[img2.xdim] = clamp(convert(Int, x), 1, size(P,img2.xdim))
indexes[img2.ydim] = clamp(convert(Int, y), 1, size(P,img2.ydim))
indsP = indices(P)
indsx, indsy = indsP[img2.xdim], indsP[img2.ydim]
indexes = RangeIndex[map(UnitRange, indsP)...]
indexes[img2.xdim] = clamp(convert(Int, x), first(indsx), last(indsx))
indexes[img2.ydim] = clamp(convert(Int, y), first(indsy), last(indsy))
if img2.zdim > 0
indexes[img2.zdim] = img2.zindex
end
Expand Down Expand Up @@ -154,13 +156,14 @@ function ImageSlice2d(img::AbstractArray, props::Dict)
end
props[:transpose] = xdim > ydim
# Start at z=1, t=1
pindexes = parentindexes(img)
pindexes = map(UnitRange, _parentindexes(img))
pdims = parentdims(img)
indexes = ntuple(i -> (i == zdim || i == tdim) ? 1 : (1:size(img, i)), ndims(img))
inds = map(UnitRange, indices(img))
indexes = ntuple(i -> (i == zdim || i == tdim) ? 1 : inds[i], ndims(img))
imslice = Base.view(img, indexes...)
bb = BoundingBox(0, size(img, xdim), 0, size(img, ydim))
sz = size(imslice)
ImageSlice2d(img, imslice, pdims, pindexes, size(imslice), bb, 1, 1, xdim, ydim, zdim, tdim)
indsx, indsy = inds[xdim], inds[ydim]
bb = BoundingBox(first(indsx)-1, last(indsx), first(indsy)-1, last(indsy))
ImageSlice2d(img, imslice, pdims, pindexes, _size(imslice), bb, 1, 1, xdim, ydim, zdim, tdim)
end

parentdims(A::AbstractArray) = [1:ndims(A);]
Expand All @@ -179,7 +182,7 @@ function _reslice!(img2::ImageSlice2d)
if img2.tdim > 0
newindexes[img2.tdim] = newindexes[img2.tdim][img2.tindex]
end
img2.imslice = Base.view(parent(img2.imorig), newindexes...)
img2.imslice = Base.view(_parent(img2.imorig), newindexes...)
img2
end

Expand Down Expand Up @@ -317,7 +320,7 @@ end
# Display a labeled image: in the status bar that shows information about the pixel under the mouse pointer,
# display the label value rather than the pixel value.
function imshowlabeled(img::AbstractArray, label::AbstractArray; proplist...)
size(img) == size(label) || throw(DimensionMismatch("size $(size(label)) of label array disagrees with size $(size(img)) of the image"))
indices(img) == indices(label) || throw(DimensionMismatch("indices $(indices(label)) of label array disagree with indices $(indices(img)) of the image"))
if isa(img, ImageMeta) && !isa(label, ImageMeta)
label = shareproperties(img, label)
end
Expand Down Expand Up @@ -380,7 +383,7 @@ function canvasgrid(ny, nx; w = 800, h = 600, pad=0, name="ImageView")
grid(frame, 1, 1, sticky="nsew")
grid_rowconfigure(win, 1, weight=1)
grid_columnconfigure(win, 1, weight=1)
c = Array(Canvas, ny, nx)
c = Array{Canvas}(ny, nx)
for j = 1:nx
for i = 1:ny
c1 = Canvas(frame, w/nx, h/ny)
Expand Down Expand Up @@ -474,7 +477,7 @@ function redraw(imgc::ImageCanvas)
hbb = height(bb)
rectangle(r, bb.xmin, bb.ymin, wbb, hbb)
# In cases of transparency, paint the background color
if imgc.surfaceformat == Cairo.FORMAT_ARGB32 && !is(imgc.background, nothing)
if imgc.surfaceformat == Cairo.FORMAT_ARGB32 && imgc.background != nothing
if isa(imgc.background, CairoPattern)
set_source(r, imgc.background)
else
Expand Down Expand Up @@ -511,7 +514,7 @@ function resize(imgc::ImageCanvas, img2::ImageSlice2d)
setbb!(imgc, w, h)
set_coordinates(imgc, img2.zoombb)
r = getgc(imgc.c)
if !is(imgc.aspect_x_per_y, nothing)
if imgc.aspect_x_per_y != nothing
fill(r, imgc.perimeter)
end
redraw(imgc)
Expand Down Expand Up @@ -577,8 +580,9 @@ function zoomwheel(imgc::ImageCanvas, img2::ImageSlice2d, delta, x, y)
xmn, xmx = centeredclip(xu, width(img2)/2, xrange(img2))
ymn, ymx = centeredclip(yu, height(img2)/2, yrange(img2))
else
xmn, xmx = centeredclip(xu, 2*width(img2), (1,sizex(img2)), xrange(img2))
ymn, ymx = centeredclip(yu, 2*height(img2), (1,sizey(img2)), yrange(img2))
indsx, indsy = indicesx(img2), indicesy(img2)
xmn, xmx = centeredclip(xu, 2*width(img2), (first(indsx),last(indsx)), xrange(img2))
ymn, ymx = centeredclip(yu, 2*height(img2), (first(indsy),last(indsy)), yrange(img2))
end
zoombb(imgc, img2, BoundingBox(floor(xmn)-1, ceil(xmx), floor(ymn)-1, ceil(ymx)))
end
Expand Down Expand Up @@ -663,10 +667,10 @@ end

### Utilities ###
function allocate_surface!(imgc::ImageCanvas, w, h)
buf = Array(UInt32, w, h)
buf = Array{UInt32}(w, h)
imgc.surface = CairoImageSurface(buf, imgc.surfaceformat, flipxy = false)
if imgc.transpose
imgc.renderbuf = Array(UInt32, h, w)
imgc.renderbuf = Array{UInt32}(h, w)
end
end

Expand Down Expand Up @@ -698,7 +702,7 @@ end

# Create a checkerboard pattern (for use with transparency)
function checker(checkersize::Int; light = 0xffb0b0b0, dark = 0xff404040)
buf = Array(UInt32, 2checkersize, 2checkersize)
buf = Array{UInt32}(2checkersize, 2checkersize)
fill!(buf, light)
buf[1:checkersize,checkersize+1:2checkersize] = dark
buf[checkersize+1:2checkersize,1:checkersize] = dark
Expand All @@ -713,7 +717,7 @@ end
function rendersize(w::Integer, h::Integer, r)
ww = w
wh = h
if !is(r, nothing)
if r != nothing
if r > 1
ww = round(Integer, w*r)
else
Expand Down Expand Up @@ -744,7 +748,7 @@ function resetfirst!(s::SubArray)
pstride = 1
for j = 1:length(s.indexes)
newfirst += (first(s.indexes[j])-1)*pstride
pstride *= size(s.parent, j)
pstride *= length(indices(s.parent, j))
end
s.first_index = newfirst
s
Expand Down Expand Up @@ -772,3 +776,12 @@ function write_to_png(imgc::ImageCanvas, filename)
ctx = copy(imgc.c.backcc, imgc.canvasbb)
Cairo.write_to_png(ctx.surface, filename)
end

# Non-1 index utilities
_parentindexes(V::SubArray) = V.indexes
_parentindexes(a::AbstractArray) = indices(a)
_size(a::AbstractArray) = map(length, indices(a))
indicesx(img2::ImageSlice2d) = img2.indexes[img2.xdim]
indicesy(img2::ImageSlice2d) = img2.indexes[img2.ydim]
_parent(a::AbstractArray) = parent(a)
_parent(a::AxisArray) = a
2 changes: 1 addition & 1 deletion src/navigation.jl
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ end
# callback is an array of 5 entries, the 5th being the edit box
function addbuttons(f, sz, bkg, pad, index, orientation, callback, rng)
rotflag = orientation == "z"
ctrl = Array(Any, 7)
ctrl = Array{Any}(7)
ctrl[1], ctrl[2], ctrl[3], ctrl[4] = arrowheads(sz, rotflag)
mask = trues(sz)
const color = ("black", "green", "green", "black")
Expand Down
1 change: 1 addition & 0 deletions test/REQUIRE
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
TestImages
ImageMagick
OffsetArrays
6 changes: 5 additions & 1 deletion test/simple.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import ImageView
using Images
using Images, OffsetArrays

# Grayscale
ImageView.imshow(rand(Gray{N0f8}, 10, 10))
Expand All @@ -21,3 +21,7 @@ A[1,2,2] = NaN
A[1,3,3] = -Inf
A[1,4,4] = Inf
ImageView.imshow(colorview(RGB, A))

# Non-1 indices
A = OffsetArray(rand(11, 10), -5:5, 0:9)
ret = ImageView.imshow(A)
4 changes: 2 additions & 2 deletions test/test4d.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ sz = [201, 301, 31]
center = [(s+1)>>1 for s in sz] # ceil(Int, sz/2)
C3 = Bool[(i-center[1])^2+(j-center[2])^2 <= k^2 for i = 1:sz[1], j = 1:sz[2], k = sz[3]:-1:1]
cmap1 = round(UInt32, linspace(0,255,60))
cmap = Array(UInt32, length(cmap1))
cmap = Array{UInt32}(length(cmap1))
for i = 1:length(cmap)
cmap[i] = cmap1[i]<<16 + cmap1[end-i+1]<<8 + cmap1[i]
end
C4 = Array(UInt32, sz..., length(cmap))
C4 = Array{UInt32}(sz..., length(cmap))
for i = 1:length(cmap)
C4[:,:,:,i] = C3*cmap[i]
end
Expand Down

0 comments on commit 0ad314c

Please sign in to comment.