JuliaImages / Images.jl

An image library for Julia
http://juliaimages.org/
Other
535 stars 142 forks source link

stringmime error #237

Closed MikeInnes closed 8 years ago

MikeInnes commented 9 years ago

On the latest Images.jl (0.4.24) and Julia 0.3, I'm seeing the following error:

julia> im = convert(Image, rand(5,5))
Gray Image with ...

julia> stringmime("image/png", im)
ERROR: 
 in error at error.jl:21
 in error at /Users/mike/.julia/v0.3/Images/src/ioformats/libmagickwand.jl:150
 in setimageformat at /Users/mike/.julia/v0.3/Images/src/ioformats/libmagickwand.jl:331
 in getblob at /Users/mike/.julia/v0.3/Images/src/ioformats/libmagickwand.jl:212
 in writemime at /Users/mike/.julia/v0.3/Images/src/io.jl:205
 in base64 at base64.jl:125
 in stringmime at multimedia.jl:82
 in stringmime at multimedia.jl:88

Previously this would output the base64-encoded image (and it seems to work on Julia 0.4).

timholy commented 9 years ago

Works for me on both julia 0.4 and julia 0.3.4. What platform are you on? What does Images.LibMagick.libversion say?

MikeInnes commented 9 years ago

This is on OS X – on both Julia 0.3 and 0.4 (where it works for me) Images.LibMagick.libversion == v"6.8.9". Homebrew.jl lists imagemagick version 6.8.9-1 and doesn't change when I Homebrew.update().

I'll give this a go on some other OSs to see what happens. Let me know if there's anything else I can do to help; I'd still like to show off Images.jl in my Juno tutorial ;)

timholy commented 9 years ago

If this is something that used to work, you can certainly try a git bisect on Images. That won't help if it broke due to an OS (or ImageMagick binary) update, but if its a bug in Images that could help pinpoint the problem.

But it seems likely to be an ImageMagick problem; note that the (very unhelpful) error message is being generated by ImageMagick, and it's occurring in setimageformat. You could also add a @show format inside setimageformat and see what it outputs (it should be "png"; I guess you could try changing it to "PNG" and see if that helps).

JobJob commented 9 years ago

@one-more-minute Mike did you manage to get this working for you in Julia 0.3 ? In IJulia have basically the same issue in Julia 0.3.6 with the following code, same versions of Images and ImageMagick in Homebrew.list()

using Images, TestImages
img = testimage("fabio")

the error message is:

in error at error.jl:21
in error at ~/.julia/v0.3/Images/src/ioformats/libmagickwand.jl:149
in setimageformat at ~/.julia/v0.3/Images/src/ioformats/libmagickwand.jl:331
in getblob at ~/.julia/v0.3/Images/src/ioformats/libmagickwand.jl:211
in writemime at ~/.julia/v0.3/Images/src/io.jl:205
in base64 at base64.jl:125
in display_dict at ~/.julia/v0.3/IJulia/src/execute_request.jl:34

FYI the following returns 0 for "png","jpg","jpeg","JPEG","PNG","PNG8":

import Images.LibMagick
wand = LibMagick.MagickWand()
ccall((:MagickSetImageFormat, LibMagick.libwand), Cint, (Ptr{Void}, Ptr{Uint8}), wand.ptr, "JPG")

and run(identify -list format) in a julia prompt (http://www.imagemagick.org/script/formats.php) returns:

Format  Module    Mode  Description
-------------------------------------------------------------------------------

* native blob support
r read support
w write support
+ support for multiple images

i.e. the list is blank. When I run on a regular command line (which I assume uses my macports compiled ImageMagick) I get a long list of formats. Not sure if it's relevant but in IJulia running that command gets me a failed process: Process(identify -list format, ProcessExited(1)) [1] while loading In[11], in expression starting on line 1

MikeInnes commented 9 years ago

Unfortunately, no – I never managed to look into this more. But I get the exact same output from running those lines.

@timholy is there a way to get Images.jl to use the system ImageMagick?

timholy commented 9 years ago

Since this appears OSX-specific, calling in @staticfloat here.

I'll point out that presumably another approach would be to extend @rsrock's good work on OSXNative.jl to writing (not just reading).

staticfloat commented 9 years ago

It looks like ImageMagick is not getting the list of formats properly.

@one-more-minute, @JobJob can I ask you both to post the following output, if you haven't already:

julia> run(`which identify`)
/Users/sabae/.julia/v0.3/Homebrew/deps/usr/bin/identify

julia> run(`identify -list format`)
   Format  Module    Mode  Description
-------------------------------------------------------------------------------
      3FR  DNG       r--   Hasselblad CFV/H3D39II
        A* RAW       rw+   Raw alpha samples
      AAI* AAI       rw+   AAI Dune image
       AI  PDF       rw-   Adobe Illustrator CS2
...

julia> using Images

julia> filter(x -> contains(x, "image"), Sys.dllist())
1-element Array{String,1}:
 "/Users/sabae/.julia/v0.3/Homebrew/deps/usr/Cellar/imagemagick/6.8.9-1_1/lib/libMagickCore-6.Q16.2.dylib"

It's worth noting that I do not have imagemagick installed system-wide on my machine anywhere.

rsrock commented 9 years ago

This is definitely on my todo list. I will probably revamp the whole reader/writer, and use @one-more-minute's awesome ObjectiveC.jl package which I just discovered last week. Any plans on tagging a version of that?

On Mar 14, 2015, at 8:24 PM, Tim Holy notifications@github.com<mailto:notifications@github.com> wrote:

Since this appears OSX-specific, calling in @staticfloathttps://github.com/staticfloat here.

I'll point out that presumably another approach would be to extend @rsrockhttps://github.com/rsrock's good work on OSXNative.jl to writing (not just reading).

— Reply to this email directly or view it on GitHubhttps://github.com/timholy/Images.jl/issues/237#issuecomment-80791520.


Ronald S. Rock, Jr., Associate Professor Dept. of Biochemistry and Molecular Biology, The University of Chicago GCIS W240, 929 E. 57th St. Chicago, IL 60637 USA +1 773.702.0716 (w), +1 773.702.0439 (f) rrock@uchicago.edumailto:rrock@uchicago.edu

rsrock commented 9 years ago

On my system, I get this:

run(`which identify`)

/usr/local/bin/identify

Which is at least part of the problem. I will push a fix here shortly.

Related: staticfloat/homebrew-juliadeps#38

rsrock commented 9 years ago

Actually, I'll only have a partial fix for this issue (the $PATH setting). The main issue is that Homebrew/MacPorts/Whatever ImageMagick is being picked up, instead of @staticfloat's Julia-Homebrew package. The symptom is something like this line in .../Images/deps/deps.jl:

# Load dependencies
@checked_lib libwand "/usr/local/lib/libMagickWand-6.Q16.dylib"

That should look like:

# Load dependencies
@checked_lib libwand "/Users/rrock/.julia/v0.3/Homebrew/deps/usr/lib/libMagickWand-6.Q16.dylib"

A quick fix may be to brew unlink imagemagick, followed by a Pkg.build("Images") in julia, followed by brew link imagemagick.

MikeInnes commented 9 years ago

@staticfloat identify only works for me when installed globally via homebrew – after uninstalling run(which identify) just gives an error.

julia> filter(x -> contains(x, "image"), Sys.dllist())
1-element Array{String,1}:
 "/Users/mike/.julia/v0.3/Homebrew/deps/usr/Cellar/imagemagick/6.8.9-1/lib/libMagickCore-6.Q16.2.dylib"

@rsrock Awesome, would be great for ObjectiveC.jl to see some more use. Ping me if you need anything, and sure, I can tag a release if you need one. Do you need 0.3 compatibility? I'm hoping I can speed things up a bit with staged functions and take advantage of the new struct support at some point.

rsrock commented 9 years ago

Ok, after b6e50d55, which identify points to @staticfloat's version and run(identify -list format) gives a nice long list of image formats to work with.

MikeInnes commented 9 years ago

Ok, this is interesting – which @rsrock's patch I can run identify -list format after using Homebrew. I get a nice long list of formats. Then, after using Images, all the formats disappear – so Images.jl is nuking them somehow.

staticfloat commented 9 years ago

So let's first ensure that we all know we're on the same page as far as how BinDeps works, and how Images interacts with it.

Images has a build.jl file, which invokes BinDeps and asks BinDeps to create a deps.jl file. This deps.jl file is only recreated after calling Pkg.build("Images"), either directly or indirectly. deps.jl caches things like library file paths, so if you change something about the environment you need to be sure to run Pkg.build("Images") before expecting everything to be settled and working.

In order to create deps.jl, BinDeps will attempt to satisfy all library dependencies given it. In this case, the libwand dependency (Note it's got a bunch of aliases, but in our case we're looking at libMagickWand-6.Q16.dylib). BinDeps will search all providers it has been informed could possibly provide this library (System Paths, Homebrew.jl, etc...) and will pick the first one that requires the least effort to get working. This means that it will pick some random library that's laying around on a library search path (e.g. DYLD_LIBRARY_PATH, DYLD_FALLBACK_LIBRARY_PATH, etc....) over installing a Homebrew.jl package if it thinks it can use that library. It will, however, prefer a Homebrew.jl file over a file laying around on the system path if both are available. This also means that if it picked up a system library earlier, (and had written out an appropriate deps.jl file) even if you manually Homebrew.add("imagemagick") you will need to Pkg.build("Images") so that the deps.jl file is changed.

Now that we've got that out of the way, let's look at the specific stuff that Images.jl does with BinDeps and Homebrew.jl. Specifically, we not only ask for Homebrew.jl to install imagemagick for us, but we add an onload hook to modify some environment variables for us. I believe the issue of all the file formats disappearing is due to misconfigured environment variables, and this is likely being caused by Pkg.build("Images") not getting called before people try to call using Images. Note that this onload hook gets written out to deps.jl as well, and we should not have such a hook if Images.jl is to use a system-paths version of imagemagick. According to @rsrock's comment in another thread, that looks like it is happening, which is a huge no-no, and is definitely one bug that needs to be squashed.

rsrock commented 9 years ago

@rsrock Awesome, would be great for ObjectiveC.jl to see some more use. Ping me if you need >anything, and sure, I can tag a release if you need one. Do you need 0.3 compatibility? I'm hoping I can >speed things up a bit with staged functions and take advantage of the new struct support at some point.

@one-more-minute, Thanks! I'm still using 0.3 for the most part, but with that good stuff coming, I might have to play around with 0.4. I'm especially excited about being able to make NSrects, especially if the new struct support can handle it (although your current solution works quite well). Looking forward to making native UIs with this.

I don't think Images needs anything more involved than objc_msgsend calls. That said, it might be easier to maintain if I just hold off on this until the staged function and struct support lands, so I will probably make those changes for Images on 0.40- only.

MikeInnes commented 8 years ago

Seems to be working on master.