Cannot load image and do fftshift inside the same function

Hi all,

I encountered an error while trying to load an image and run an fftshift inside a function. My minimal working example is

using TestImages, FFTW

function f()
    img = testimage("mandrill")
    fftshift(img)
end

f()

which I have inside a test.jl file. When I include this in the REPL the first time, I get a MethodError. But the second time it works.

julia> include("test.jl");
ERROR: MethodError: no method matching size(::TiffImages.DenseTaggedImage{ColorTypes.RGB{FixedPointNumbers.N0f8}, 2, UInt32, Matrix{ColorTypes.RGB{FixedPointNumbers.N0f8}}})
The applicable method may be too new: running in world age 29644, while current world is 29651.
Closest candidates are:
  size(::TiffImages.DenseTaggedImage) at /Users/albertxu/.julia/packages/TiffImages/10dKE/src/types/dense.jl:24 (method too new to be called from this world context.)
  size(::AbstractArray{T, N}, ::Any) where {T, N} at abstractarray.jl:38
  size(::Union{LinearAlgebra.Adjoint{T, var"#s832"}, LinearAlgebra.Transpose{T, var"#s832"}} where {T, var"#s832"<:(AbstractVector{T} where T)}) at /Users/julia/buildbot/worker/package_macos64/build/usr/share/julia/stdlib/v1.6/LinearAlgebra/src/adjtrans.jl:196
  ...
Stacktrace:
 [1] size
   @ ./abstractarray.jl:38 [inlined]
 [2] #24
   @ ~/.julia/packages/AbstractFFTs/JebmH/src/definitions.jl:363 [inlined]
 [3] ntuple
   @ ./ntuple.jl:19 [inlined]
 [4] fftshift(x::TiffImages.DenseTaggedImage{ColorTypes.RGB{FixedPointNumbers.N0f8}, 2, UInt32, Matrix{ColorTypes.RGB{FixedPointNumbers.N0f8}}}, dim::UnitRange{Int64}) (repeats 2 times)
   @ AbstractFFTs ~/.julia/packages/AbstractFFTs/JebmH/src/definitions.jl:363
 [5] f()
   @ Main ~/.julia/dev/SimpleCTF/test.jl:5
 [6] top-level scope
   @ ~/.julia/dev/SimpleCTF/test.jl:8

julia> include("test.jl");

julia>

However, calling either testimage or fftshift outside the function works as well.

Ah, yeah, it looks like the image loading code inside testimage (which I think uses ImageIO.jl internally) does some magic to lazily load different packages to handle different image types.

I can think of two different ways to avoid this issue:

  1. Use invokelatest to run functions that depend on img within the context of your function:
julia> using TestImages

julia> function f()
         img = testimage("mandrill")
         Base.invokelatest(size, img)
       end
f (generic function with 1 method)

julia> f()
(512, 512)

You can learn more about invokelatest here: Essentials · The Julia Language

  1. Ensure that TiffImages is already loaded so that testimage doesn’t need to do its lazy loading in the background:
julia> using TestImages, TiffImages

julia> function f()
         img = testimage("mandrill")
         size(img)
       end
f (generic function with 1 method)

julia> f()
(512, 512)

I would also consider creating an issue over at GitHub - JuliaImages/TestImages.jl: Standard test images for Julia , since I’m sure you’re not the only person to have had this problem.

2 Likes

See also World Age problem when loading tif and multiplying result by a number · Issue #283 · JuliaIO/FileIO.jl · GitHub