Making images as big as possible (max width) in pluto notebooks

I am doing some image analysis in Pluto and everythign is amazing… except I can’t control how big the images are!

I have the obligatory column embiggener html code at the top

html"""<style>
main {
    max-width: 96%;
    margin-left: 1%;
    margin-right: 2% !important;
}
</style>
"""

but the images seem to refuse to grow bigger beyond a particular point. I have Images.jl loaded which loads ImageShow, but I want to fill up the screen! How do I change the image display size?

As I make the images bigger, they get bigger…

and then past a certain threshold they get smaller again to some predetermined fixed size which cannot be changed.

Further increasing the size of the figure does nothing increases the size until a certain threshold is reached at which point the image size is reduced again.
Thanks for the help!

Cannot reproduce using empty Figures from Makie.jl in a notebook I had running.

I put your html snippet in and made several empty figures with different sizes and they just grow until they fill out the space. So I am not sure what causes this shrinking for you. Did you try to inspect the CSS and DOM using the developer tools? Maybe Images.jl somehow does some shrinking of the output if it thinks it too big for the screen? I don’t think Pluto.jl is to blame here.

Im not a html person really but I found the element, the png resource in “blob” is itself stored at a lower resolution, does that mean its a problem with Images.jl?

What excatly determines how the output is saved as an html resource?

<pluto-output class="rich_output " ...
aria-label="Result of unlabeled cell:" 
mime="image/png">

<assignee aria-hidden="true" translate="no">
</assignee><div>
<img type="image/png" src="blob:http://localhost:1240/5ab27dbf-6439-48a0-b701-07b6d4a2dcd4"></div></pluto-output>

Do these styles from PlutoStyles.jl work for your images?

Im not sure Im currently able to get pluto styles working, but I get the same behaviour with

using PlutoStyles
import pluto
Pluto.run()

(thats the defaults right?)

Do you have an MWE image to demonstrate the effect?

begin
	using Images
	using TestImages
end
# run in successive cells to see fabio 
# get larger and then smaller again.
imresize(testimage("fabio_color_512"); ratio= 1.0)
imresize(testimage("fabio_color_512"); ratio= 1.5)
imresize(testimage("fabio_color_512"); ratio= 2.0)

Yeah I think it’s not a pluto/css issue, images shown get smaller in terms of number of pixels.

Ok yeah you can see that images are size controlled carefully on the output in the ImageShow package.

I guess since pluto just reuses show methods, this code (prevents your terminal from exploding with giant arrays) gets in the way. The modularity comes from using restrict factor-of-2 downsampling for speed. So I will try and remove this dependency and report back.

Edit: without ImageShow I cant display the images properly. maybe someone knows how to coordinate the iocontext :thumbnailsize with the base size of the image?

Edit2: I guess actually its the maxpixel term in corrected linked method here. How do I pass a different maxpixel keyword? I dont know what IO variable pluto is sending show.

I can overwrite the method buuuut seems a little risky.

1 Like

The problem is that the show method in ImagesShow

Base.show(io::IO, mime::MIME"image/png", img::AbstractMatrix{C};
                   minpixels=10^4, maxpixels=10^6)

enforces this maxpixels keyword by default (or unless get(io,:full_fidelity) == true).

But I don’t know how to increase the maxpixels keyword to show in the Pluto context. Here are some ideas.

  1. save the image directly as a resource for the html code to find in a way that mimics Plutos internal methods that call show.
  2. Pass a keyword, say maxpixels=10^7 to a show call somewhere inside Pluto (remember, pluto will just try and REshow the output of a show call)
  3. set somewhere in stdout::IO a field :full_fidelity to true (how ???)
  4. Overwrite this show method from inside the the package module, maybe using ImageShow.eval?
  5. submit a PR to ImageShow requesting that maxpixels be increased by a factor of 10 (would change behaviour around the julia ecosystem).

urrgh. Which idea is the least stupid?

I think I would do this but you don’t need to use eval. Just copy the relevant code of ImageShow where it defines the method in Base and add that to your notebook. That is sufficient to overwrite the method (and will cause some recompilation once). If the method is rather complex and uses a lot of ImageShow internals, then maybe you can find a simpler method to overwrite higher in the call stack.

1 Like

Also pinging @fonsp. He probably knows best how to customize the display within Pluto.jl

1 Like

Ok! I got the method overwritten, actually without any definitions from ImageShow.

function Base.show(io::IO, mime::MIME"image/png",  img::AbstractMatrix{C}) where {C<:Colorant}
        FileIO.save(FileIO.Stream{format"PNG"}(io), img)
end

and now everything is scaled to fit the window! It still kinda bothers me though that theres a keyword that does what I want and I cant use it but thats an aesthetic issue. I can go ahead and remove ImageShow entirely as a dependency.

2 Likes

Yep this is a feature of ImageShow! There is actually a way to control the IO context, using PlutoUI.WithIOContext. Normally, this lets you change flags for just that one render, like : full_fidelity => true.

But it’s not working in this very special case because of this whole thing…, and the HTML show method does not seem to get the IO context… weird! Well, I tried!

1 Like

I made html show method: use IOContext from original renderer by fonsp · Pull Request #60 · JuliaImages/ImageShow.jl · GitHub to fix this, after that PR and release you can do:

WithIOContext(
	some_image,
	:full_fidelity => true,
)

to tell ImageShow.jl not to downscale the image.

3 Likes