-
Notifications
You must be signed in to change notification settings - Fork 32
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Display custom type with PNG support #307
Comments
I think we're confusing two distinct things: Are you thinking of some viewer that can render PNGs directly? For example, are you trying to show this image in a web interface or via VSCode directly? |
Yes. Is ImageView.jl not the right tool for this? Ideally I only want to implement I hoped that ImageView.jl could display any custom type directly, if the type can be displayed for example as function imshow(img::Any)
if showable("image/png", img)
# open a window and render the PNG data returned by Base.show
elseif showable("image/jpeg", img)
# open a window and render the JPEG data returned by Base.show
else
throw(ArgumentError("$(typeof(img)) can't be rendered as an image"))
end
end I could also imagine that it happens automatically if ImageView is loaded, like julia> foo = Foo()
# `foo` is displayed as text here
julia> using ImageView
julia> foo
# now `foo` opens as an image in an external window (or when using just |
Typically what you want to do is provide a Some displays may understand PNG such as a web browser or a VS Code. See the Julia images documentation. |
While ImageView.jl currently doesn't provide an AbstractDisplay implementation, I saw that ImageInTerminal.jl does support it. However, I believe that its implementation is not entirely correct. It claims that it has support for So when I test the code from above with ImageInTerminal.jl, it still doesn't work: julia> struct Foo end
julia> foo = Foo()
Foo()
julia> displayable("image/png")
false
julia> using PNGFiles, TestImages, ImageInTerminal
julia> displayable("image/png")
true
julia> showable("image/png", foo)
false
julia> Base.show(io::IO, ::MIME"image/png", ::Foo) = PNGFiles.save(io, testimage("mandrill"))
julia> showable("image/png", foo)
true
julia> foo
Foo() Therefore, instead of the line Base.displayable(::TerminalGraphicDisplay, ::MIME"image/png") = true at https://github.com/JuliaImages/ImageInTerminal.jl/blob/340ebebda60b59aa59246938f390c1bfd131958f/src/display.jl#L7, it should actually be Base.displayable(::TerminalGraphicDisplay, ::MIME"image/png") = false
Base.displayable(::TerminalGraphicDisplay, ::MIME"image/png", ::Vector{UInt8}) = true
Base.displayable(::TerminalGraphicDisplay, ::MIME"image/png", ::AbstractArray{<:Colorant}) = true I think there was a misunderstanding in that package about how Please also compare how my example code from above works in a Pluto notebook; here everything works as expected: Update: I created a PR for the ImageInTerminal package at JuliaImages/ImageInTerminal.jl#76 |
Support for showing PNG's via
|
Thank you for the suggestion. It works well with the example using the file from TestImages, however it turned out that this code randomly crashes (sometimes immediately, or after a few seconds, or sometimes if I resize the window) if it is used with my own implementation of So I ended up using the approach from CairoMakie, which simply writes the PNG to a temporary file on disk and then it opens the file with the default image viewer: using Scratch: @get_scratch!
function preview(x::Foo)
filepath = joinpath(@get_scratch!("preview"), "preview.png")
open(filepath, "w") do file
show(file, "image/png", x)
end
command = @static Sys.iswindows() ? `powershell.exe start $filepath` : `open $filepath`
run(command)
nothing
end |
OK, thanks for letting me know, I'll look into it -- the memory is supposed to be copied, but maybe there is a reference counting bug somewhere. I'm glad you found an alternative method that works. |
How can I use
imshow
to display an image of my custom type which has support for theimage/png
MIME type viaBase.show
?Is it not supported, or is
imshow
not the appropriate function for this? Or does ImageView support some kind of AbstractDisplay, so that I could writedisplay(ImageViewDisplay, Foo())
?Minimum non-working example:
The text was updated successfully, but these errors were encountered: