Skip to content

Conversation

@tinevez
Copy link
Contributor

@tinevez tinevez commented Nov 29, 2025

This is to enable in BDV a better display control for label images

This converter allows for better controling the visibility of ARGB segmentation. The scale value is used to alter the brightness of colors, which is better suited than altering R G and B in bulk.

This could be used in the BDV, to finely control the visibility of a segmentation overlay in the shape of an ARGB image.

This is to enable in BDV a better display control for label images

This converter allows for better controling the visibility of ARGB
segmentation. The scale value is used to alter the brightness of
colors, which is better suited than altering R G and B in bulk.

This could be used in the BDV, to finely control the visibility of a
segmentation overlay in the shape of an ARGB image.
@tpietzsch
Copy link
Member

If possible, I would like to avoid the dependency on java.awt.Color.

We could just inline the Color.HSBtoRGB and Color.RGBtoHSB implementations.
This would also avoid to have the (non-threadsafe) float[] hsb array.
But I strongly suspect that full conversion to/from HSB is not necessary to change the brightness.
I didn't look into the math (https://en.wikipedia.org/wiki/HSL_and_HSV#HSV_to_RGB etc) in detail, but from looking over it, I think there should be shortcuts. Do you want to dig into that? (Otherwise, I can also dig a bit deeper when I find time)

@tpietzsch
Copy link
Member

tpietzsch commented Dec 30, 2025

I couldn't resist... I think it should be more or less:

v := max(r,g,b)
m := min(1, v/scale) - v

and then

r' := min(255, r+m)
g' := min(255, g+m)
b' := min(255, b+m)

Could you try whether that works?

This code is adapted from https://www.cs.rit.edu/~ncs/color/t_convert.html
with feedback from Claude AI.
It improves the previous version by getting rid of the Color dependency
and by being thread safe (removing the need for a float[] field).
@tinevez
Copy link
Contributor Author

tinevez commented Dec 31, 2025

Done!
Tested with the BDV overlaying a segmentation results as a label image. The scale properly alters the visibility of the segmentation overlay without touching the teint.

@tinevez
Copy link
Contributor Author

tinevez commented Jan 7, 2026

Here is what I have tested, with a label image overlay in the BDV, in 'Sum' mode, and adjusting the scale to 255, 122, and 0.

The current implementation

https://github.com/imglib/imglib2/blob/master/src/main/java/net/imglib2/display/ScaledARGBConverter.java#L102

imglib2original1 imglib2original2 imglib2original3

Scaling brightness via HSB conversion

private static final int getScaledColor( final int color, final double scale )

HDBconverter1 HDBconverter2 HDBconverter3

Simple RGB scaling

https://github.com/imglib/imglib2/blob/argb-converter/src/main/java/net/imglib2/display/ScaledBrightnessARGBConverter.java#L47

simpleRGBscaling1 simpleRGBscaling2 simpleRGBscaling3

Conclusion

The simple RGB scaling gives perceptually similar results and is considerably simpler. I suggest we stick to it.

@tpietzsch
Copy link
Member

Could you try what I suggested above:
(input color: r,g,b)
v := max(r,g,b)
m := min(1, v/scale) - v
r' := min(255, r+m)
g' := min(255, g+m)
b' := min(255, b+m)
(output color: r,g,b)

I think this should be exactly the same as via HSB conversion.
(I just took the "convert-to-HSB-then-modify-S-then-convert-to-RGB" sequence and simplify the equations).

@tinevez
Copy link
Contributor Author

tinevez commented Jan 7, 2026

I had tried and it does not seem to work. The display is unsensitive to scale and the colors are wrong. Here is what I implemented

	private static final int getScaledColor( final int color, final double scale )
	{
		final int r = ARGBType.red( color );
		final int g = ARGBType.green( color );
		final int b = ARGBType.blue( color );
		final int v = Math.max( r, Math.max( g, b ) );
		final double m = Math.min( 1., v / scale ) - v;

		final int nr = ( int ) Math.min( 255, r + m );
		final int ng = ( int ) Math.min( 255, g + m );
		final int nb = ( int ) Math.min( 255, b + m );

		return 0xff000000 | ( nr << 16 ) | ( ng << 8 ) | nb;
	}
Screenshot 2026-01-07 at 15 36 29

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants