Is there a way to fix JUCE Colours?

auto bounds = getLocalBounds();
auto c = juce::Colour::fromString("#FF1A1A1A");

g.setColour(c);
g.fillRect(bounds);

bounds = bounds.reduced(50);

g.beginTransparencyLayer(0.1f);
g.setColour(c);
g.fillRect(bounds);
g.endTransparencyLayer();

results in this:
imgUglyTranspLayer
although it should result in this:
imgNormal

things get really ugly when using a colour and the same colour with different opacity in a colourGradient:

auto gradient = juce::ColourGradient::horizontal(c.withAlpha(0.f), c, bounds);
    g.setGradientFill(gradient);
    g.fillRect(bounds); //ugh

results in
imgUgly

is there any way to avoid this? Im afraid this is caused by lower colour bit depth in JUCE and we cant do anything about it.

Something wrong with your images or my browser

Could be also that you just have a crappy screen. I don’t see anything in the images.

1 Like

There’s a darker rectangle in the centre of those images which can be verified using a colour picker tool - it’s probably more noticable on a higher-contrast screen. The outer colour is FF1A1A1A, which is correct, while the inner colour is FF191919.

I believe this is a known issue - there was another thread about the same issue a few weeks ago but I can’t find it to link it now.

Oh yes, you are right. The forum background is white so it makes the subtle differences hard to see. Very nasty.

Is there even a solution to this problem? I think every graphics tool suffers from this more less.

Wouldnt be great if I cant use colour gradients with my brand colour at all.

I often find alpha blending to kinda suck in comparison to full opacity colors. Just out of curiosity. Can’t you do it without alpha?

When I first saw the images I wondered whether the difference lies in colors that only smart people can see. After your explanation I understand that this is actually the case. The emperor is clothed after all.

I fully agree, but here is the problem: I have an envelope analyzer component which updates frequently, and there are a lot of graphics calls in there. This should be blended in with the background like this:
image

Replacing all paint calls colours with gradients or changing the Graphics alpha is not possible (because I paint into an image and to make the waveform look like its moving I have to paint the image at different positions), so I dont have a choice.

I do this to avoid repainting a huge path every frame, so I might have to start looking into openGL…

Don’t know if you can use it, but this trick helped me in a similar situation. You create a gradient alpha mask and render with that.

	juce::Image mask (juce::Image::PixelFormat::SingleChannel, bounds.getWidth (), int (std::ceil (FadeHeight)), true);
	std::unique_ptr<juce::LowLevelGraphicsContext> ctx (mask.createLowLevelContext ());
	juce::Graphics mg (*ctx);
	mg.setGradientFill (juce::ColourGradient::vertical (juce::Colours::white, 0, colour.withAlpha (0.f), topFadeDistance));
	mg.fillRect (bounds.withHeight (FadeHeight));
	g.reduceClipRegion (mask, juce::AffineTransform ());

This way you don’t need to fake it by rendering a background color to transparent gradient on top of stuff you want to fade away.

1 Like

great idea, turns out it doesnt work either.

Interesting. How so?

It creates the same artifacts as the other methods from my pictures.
Short term I will have to redesign this product, but a long term solution on the juce side of things would be really great.

Does the curve image have also background? the same color as the real background or where do the artefacts appear. I could imagine this being drawn in a way that there needs to be no same color drawn at the same pixel in fully opaque background and masked foreground. Use the mask only on the curve image that has fully transparent background so that only the curves get masked.

1 Like

The image contained the same colour as a background, and removing the background from the image did the trick! Thank you very much! I used to draw the same colour to remove old image content and paint the bg in one place, but I could have just used image.clear as well.
For everyone else having this issue:

  1. draw the full opacity colour first
  2. use a transparency layer to paint only all the other colours
2 Likes

Awesome! I like this method particularly because it does actually what it looks like instead of faking it. I believe JUCE is the only framework that i’ve used where this is possible (or easy to the extend that it’s practical). Have been forced to fake it so so many times and always with unsatisfying results.

2 Likes

Any chance of a GIF?