napari
napari copied to clipboard
Additive layer blending is not suited for light background canvas
🐛 Bug
Image layer with additive blending is not visible on the napari light theme (If there is no black layer bellow). To solve this I create #2103 but @sofroniewn told me that It should be solved another way.
To Reproduce
Steps to reproduce the behavior:
- Load single layer
- Change the theme to light
- Change layer blending to additive
Expected behavior
Additive blending should not get color from canvas.
Environment
-
Please copy and paste the information at napari info option in help menubar here:
-
Any other relevant information:
Additional context
Thanks for making this issue! Right now I think blending is handled on the vispy side, but we should look into this!!
As it is assigned to 0.4 then we should focus now on #2103?
As it is assigned to 0.4 then we should focus now on #2103?
I made this one 0.4 as it might be harder, require changes to vispy (i.e. not even be in napari) - I'm not sure. I would do some investigations though. Maybe there is an easy fix and then we can get it in for 0.4.4
I think for light backgrounds, additive should be changed to subtractive. Then you'd get an effect like in this tweet: https://twitter.com/christlet/status/1133729602696884224, which is nice! (But maybe you also need to take the complement of the colormap, I need to think about it.) Anyway, yes, this will probably require fiddling with the image layer shaders and eventually contributed to VisPy...
I need to programmatically add multiple layers. I could add a hook that on each layer reorder update blending. I could also update the canvas color. There are possible multiple workarounds.
And this workaround will not work with shifted or multiple size layers (second bigger than first)
Having a subtractive blending mode might be interesting. Right now the mode gets passed to https://github.com/vispy/vispy/blob/7e7db49b7874a804b9c4e47392f0321e3dd6e269/vispy/visuals/visual.py#L342-L353 which in turn goes to gloo.set_state which you can read about here - https://github.com/vispy/vispy/blob/b6cbf11bd506d48c435c6e01e36e89fc54a16d1e/vispy/gloo/wrappers.py#L440-L491 it is quite flexible and actually shouldn't require a PR to vispy, we could set from napari with what we wanted with custom functions
I have a multichannel image that I am viewing in Napari. The blending works great for LUTs that emulate illuminance/fluorescence data (dark background). I would like to emulate bright field/absorbance images (white background) though. Is there a workaround to allow blending of images with a white background?
Hi @Michael-L-Miller
It's something I've been working on.
It's a long time coming, as you can see from a discussion here, with this post being a sort of summary.
https://github.com/napari/napari/discussions/3914#discussioncomment-2586389
and a PR implementing minimum blending here:
https://github.com/napari/napari/pull/4875
Any feedback from you would be very welcome, whether on the concept or the implementation.
Hi @psobolewskiPhD
This looks great. I am still testing it out but I am able to view several channels with white backgrounds which is exactly what I needed.
@Michael-L-Miller I'm happy to hear that. Are you using custom colormaps/LUTs? Does the lack of opacity control bother you/affect your work?
The lack of opacity control does not bother me.
Yes, I am using colormaps to emulate hematoxylin and eosin for the channel. The image source is was an H&E stained whole slide image which was separated into hematoxylin only and eosin only images. After additional processing/analysis, I ultimately view the images in Napari and would like emulate the look of each stain.
colorMapHematoxylin = {
'colors': [[1,1,1,1], [111/255, 36/255, 178/255,1]], #empirically determined
'name': 'Hematoxylin',
'interpolation': 'linear'}
colorMapEosin = {
'colors': [[1,1,1,1], [211/255,50/255,84/255,1]], #empirically determined
'name': 'Eosin',
'interpolation': 'linear' }
cmapList=[colorMapHematoxylin, colorMapEosin]
viewer.open("path/to/img", channel_axis=0, name=channels, colormap=cmapList)
Left = both channels in 'additive' blending mode. Right = first channel in 'minimum' blending mode.

Awesome—I hadn't thought of that use case! Glad it's working for you. If you have any more feedback, let me know.
@Michael-L-Miller @Czaki With 0.4.17 minimum blending mode is released.
Also, it's possible to change the canvas color thanks to: https://github.com/napari/napari/pull/2270
I think we can close? I mean it's not addressing the underlying issue of how additive blending works, but I don't think that can be changed really.
Thanks so much. I think so too.
On Nov 12, 2022, at 1:33 PM, Peter Sobolewski @.***> wrote:
@Michael-L-Miller https://github.com/Michael-L-Miller @Czaki https://github.com/Czaki With 0.4.17 minimum blending mode is released. Also, it's possible to change the canvas color thanks to: #2270 https://github.com/napari/napari/pull/2270 I think we can close?
— Reply to this email directly, view it on GitHub https://github.com/napari/napari/issues/2140#issuecomment-1312546267, or unsubscribe https://github.com/notifications/unsubscribe-auth/AI6IEEMP3ZWLXRY2UJVBD53WH7PHHANCNFSM4WLA5KEA. You are receiving this because you were mentioned.