JuliaIO / ImageIO.jl

Load images in Julia. Designed for FileIO interaction. Supports PNG and Portable Bitmap formats
MIT License
28 stars 11 forks source link

show(io, MIME("image/png"), img) is broken #6

Closed fonsp closed 3 years ago

fonsp commented 4 years ago

Setup

(@v1.4) pkg> add Images ImageIO
   Updating registry at `~/.julia/registries/General`
   Updating git-repo `https://github.com/JuliaRegistries/General.git`
  Resolving package versions...
  Installed libfdk_aac_jll ─ v0.1.6+3
  Installed FreeType2_jll ── v2.10.1+3
  Installed OpenSSL_jll ──── v1.1.1+5
  Installed Bzip2_jll ────── v1.0.6+3
  Installed Opus_jll ─────── v1.3.1+2
  Installed x265_jll ─────── v3.0.0+2
  Installed libvorbis_jll ── v1.3.6+5
  Installed FriBidi_jll ──── v1.0.5+4
  Installed libass_jll ───── v0.14.0+3
  Installed LAME_jll ─────── v3.100.0+2
  Installed Ogg_jll ──────── v1.3.4+1
  Installed FileIO ───────── v1.4.1
   Updating `~/.julia/environments/v1.4/Project.toml`
  [82e4d734] + ImageIO v0.3.0
  [916415d5] + Images v0.22.4
   Updating `~/.julia/environments/v1.4/Manifest.toml`
  [621f4979] + AbstractFFTs v0.5.0
  [13072b0f] + AxisAlgorithms v1.0.0
  [39de3d68] + AxisArrays v0.4.3
  [6e34b625] ↑ Bzip2_jll v1.0.6+2 ⇒ v1.0.6+3
  [fa961155] + CEnum v0.4.1
  [aafaddc9] + CatIndices v0.2.1
  [c3611d14] + ColorVectorSpace v0.8.5
  [ed09eef8] + ComputationalResources v0.3.2
  [150eb455] + CoordinateTransformations v0.6.0
  [dc8bdbbb] + CustomUnitRanges v1.0.0
  [b4f34e82] + Distances v0.8.2
  [da5c29d0] + EllipsisNotation v0.4.0
  [4f61f5a4] + FFTViews v0.3.1
  [7a1cc6ca] + FFTW v1.2.2
  [f5851436] + FFTW_jll v3.3.9+5
  [5789e2e9] + FileIO v1.4.1
  [d7e528f0] ↑ FreeType2_jll v2.10.1+2 ⇒ v2.10.1+3
  [559328eb] ↑ FriBidi_jll v1.0.5+3 ⇒ v1.0.5+4
  [a2bd30eb] + Graphics v1.0.2
  [bbac6d45] + IdentityRanges v0.3.1
  [2803e5a7] + ImageAxes v0.6.4
  [f332f351] + ImageContrastAdjustment v0.3.5
  [a09fc81d] + ImageCore v0.8.14
  [51556ac3] + ImageDistances v0.2.7
  [6a3955dd] + ImageFiltering v0.6.14
  [82e4d734] + ImageIO v0.3.0
  [bc367c6b] + ImageMetadata v0.9.1
  [787d08f9] + ImageMorphology v0.2.8
  [2996bd0c] + ImageQualityIndexes v0.1.4
  [4e3cecfd] + ImageShow v0.2.3
  [02fcd773] + ImageTransformations v0.8.5
  [916415d5] + Images v0.22.4
  [9b13fd28] + IndirectArrays v0.5.1
  [1d5cc7b8] + IntelOpenMP_jll v2018.0.3+0
  [a98d9a8b] + Interpolations v0.12.10
  [8197267c] + IntervalSets v0.5.1
  [c1c5ebd0] ↑ LAME_jll v3.100.0+1 ⇒ v3.100.0+2
  [856f044c] + MKL_jll v2020.1.216+0
  [dbb5928d] + MappedArrays v0.2.2
  [e94cdb99] + MosaicViews v0.2.2
  [6fe1bfb0] + OffsetArrays v1.1.2
  [e7412a2a] ↑ Ogg_jll v1.3.4+0 ⇒ v1.3.4+1
  [458c3c95] ↑ OpenSSL_jll v1.1.1+4 ⇒ v1.1.1+5
  [91d4177d] ↑ Opus_jll v1.3.1+1 ⇒ v1.3.1+2
  [f57f5aa1] + PNGFiles v0.3.0
  [5432bcbf] + PaddedViews v0.5.5
  [d96e819e] + Parameters v0.12.1
  [b3c3ace0] + RangeArrays v0.3.2
  [c84ed2f1] + Ratios v0.4.0
  [6038ab10] + Rotations v1.0.1
  [699a6c99] + SimpleTraits v0.9.2
  [06e1c1a7] + TiledIteration v0.2.4
  [3a884ed6] + UnPack v1.0.1
  [efce3f68] + WoodburyMatrices v0.5.2
  [83775a58] ↑ Zlib_jll v1.2.11+14 ⇒ v1.2.11+15
  [0ac62f75] ↑ libass_jll v0.14.0+2 ⇒ v0.14.0+3
  [f638f0a6] ↑ libfdk_aac_jll v0.1.6+2 ⇒ v0.1.6+3
  [b53b4c65] + libpng_jll v1.6.37+3
  [f27f6e37] ↑ libvorbis_jll v1.3.6+4 ⇒ v1.3.6+5
  [dfaa095f] ↑ x265_jll v3.0.0+1 ⇒ v3.0.0+2

julia> using Images
[ Info: Precompiling Images [916415d5-f1e6-5110-898d-aaa5f9f070e0]

julia> i = Gray.(rand(4,4))
4×4 Array{Gray{Float64},2} with eltype Gray{Float64}:
 Gray{Float64}(0.214658)  Gray{Float64}(0.126223)   Gray{Float64}(0.502446)  Gray{Float64}(0.794309)
 Gray{Float64}(0.721307)  Gray{Float64}(0.0503738)  Gray{Float64}(0.660713)  Gray{Float64}(0.271351)
 Gray{Float64}(0.399031)  Gray{Float64}(0.943621)   Gray{Float64}(0.996223)  Gray{Float64}(0.432082)
 Gray{Float64}(0.875635)  Gray{Float64}(0.771724)   Gray{Float64}(0.890013)  Gray{Float64}(0.457217)

Calling the show method:

julia> show(stdout, MIME("image/png"), i)
[ Info: Precompiling ImageIO [82e4d734-157c-48bb-816b-45c225c6df19]
[ Info: Precompiling PNGFiles [f57f5aa1-a3ce-4bc8-8ab9-96f992907883]
Errors encountered while saving nothing.
All errors:
===========================================
MethodError: no method matching save(::Base.GenericIOBuffer{Array{UInt8,1}}, ::Array{Gray{Float64},2}, ::Pair{Symbol,ImageShow.var"#14#16"})
Closest candidates are:
  save(::IO, ::S; compression_level, compression_strategy, filters, palette) where {T, S<:Union{AbstractArray{T,3}, AbstractArray{T,2} where T}} at /home/fons/.julia/packages/PNGFiles/y75yo/src/io.jl:285
  save(::String, ::S; compression_level, compression_strategy, filters, palette) where {T, S<:Union{AbstractArray{T,3}, AbstractArray{T,2} where T}} at /home/fons/.julia/packages/PNGFiles/y75yo/src/io.jl:253
===========================================
ArgumentError: Package ImageMagick not found in current path:
- Run `import Pkg; Pkg.add("ImageMagick")` to install the ImageMagick package.

===========================================
MethodError: no method matching save(::FileIO.Stream{FileIO.DataFormat{:PNG},Base.GenericIOBuffer{Array{UInt8,1}}}, ::Array{Gray{Float64},2}; mapi=ImageShow.var"#14#16"())
Closest candidates are:
  save(::FileIO.File{FileIO.DataFormat{:PNG}}, ::Any) at /home/fons/.julia/packages/FileIO/DzfYr/src/mimesave.jl:6 got unsupported keyword argument "mapi"
  save(::FileIO.File{FileIO.DataFormat{:SVG}}, ::Any) at /home/fons/.julia/packages/FileIO/DzfYr/src/mimesave.jl:16 got unsupported keyword argument "mapi"
  save(::FileIO.File{FileIO.DataFormat{:PDF}}, ::Any) at /home/fons/.julia/packages/FileIO/DzfYr/src/mimesave.jl:26 got unsupported keyword argument "mapi"
  ...
===========================================

Fatal error:
ERROR: MethodError: no method matching save(::Base.GenericIOBuffer{Array{UInt8,1}}, ::Array{Gray{Float64},2}, ::Pair{Symbol,ImageShow.var"#14#16"})
Closest candidates are:
  save(::IO, ::S; compression_level, compression_strategy, filters, palette) where {T, S<:Union{AbstractArray{T,3}, AbstractArray{T,2} where T}} at /home/fons/.julia/packages/PNGFiles/y75yo/src/io.jl:285
  save(::String, ::S; compression_level, compression_strategy, filters, palette) where {T, S<:Union{AbstractArray{T,3}, AbstractArray{T,2} where T}} at /home/fons/.julia/packages/PNGFiles/y75yo/src/io.jl:253
Stacktrace:
 [1] handle_error(::MethodError, ::FileIO.Stream{FileIO.DataFormat{:PNG},Base.GenericIOBuffer{Array{UInt8,1}}}) at /home/fons/.julia/packages/FileIO/DzfYr/src/error_handling.jl:82
 [2] handle_exceptions(::Array{Any,1}, ::String) at /home/fons/.julia/packages/FileIO/DzfYr/src/error_handling.jl:77
 [3] save(::FileIO.Formatted, ::Any; options::Base.Iterators.Pairs{Symbol,ImageShow.var"#14#16",Tuple{Symbol},NamedTuple{(:mapi,),Tuple{ImageShow.var"#14#16"}}}) at /home/fons/.julia/packages/FileIO/DzfYr/src/loadsave.jl:217
 [4] show(::Base.GenericIOBuffer{Array{UInt8,1}}, ::MIME{Symbol("image/png")}, ::Array{Gray{Float64},2}; minpixels::Int64, maxpixels::Int64, mapi::Function) at /home/fons/.julia/packages/ImageShow/9kpaq/src/showmime.jl:43
 [5] show at /home/fons/.julia/packages/ImageShow/9kpaq/src/showmime.jl:28 [inlined]
 [6] __binrepr(::MIME{Symbol("image/png")}, ::Array{Gray{Float64},2}, ::Nothing) at ./multimedia.jl:157
 [7] _binrepr at ./multimedia.jl:0 [inlined]
 [8] #repr#1 at ./multimedia.jl:145 [inlined]
 [9] repr(::MIME{Symbol("image/png")}, ::Array{Gray{Float64},2}) at ./multimedia.jl:145
 [10] top-level scope at REPL[4]:1
fonsp commented 4 years ago

Should I post this issue to Images.jl instead?

shashi commented 4 years ago

How does this work in Jupyter though.

Edited: (I mean showing an Image does work, I tried it. But why is it different in Pluto vs Jupyter.)

fonsp commented 4 years ago

Could be because of the IOContext - could you try calling show(stdout, MIME”image/png”(), i) inside jupyter?

fonsp commented 4 years ago

It's fixed if I also install ImageMagick:

(@v1.4) pkg> add Images ImageIO ImageMagick

julia> using Images

julia> i = Gray.(rand(4,4))

julia> show(stdout, MIME("image/png"), i)
[ Info: Precompiling ImageMagick [6218d12a-5da1-5696-b52f-db25d2ecc6d1]
�PNG

IHDRdU�ʈgAMA��
�P���T@tT��a��n��`�Lpm�9�~����p��Q<bKGD���̿zIDATh��ϡ
;R����0��@ �6�r�p��u}�@ ���3�)����@ H�%�G
�>]�@ �@�� %�@IEND�B`�253
fonsp commented 4 years ago

The 4-errors-in-1 made this difficult to find - is there a way to make the error message more helpful?

shashi commented 4 years ago
show(stdout, MIME”image/png”(), i)

Haha I think Jupyter does a Base64 encoding here... and send that in a JSON, which the front end shows by creating an img tag with src=data:bas64....

You probably already know that.

fonsp commented 4 years ago

But then you are still just calling show(io, MIME"image/png"(), i) right? Except into an IOBuffer or base64 pipe instead of to your pixels directly. I don't get why it works for jupyter...

fonsp commented 3 years ago

Awesome, thanks!!