Hi,
In a plugin i work on, i fade out a complex image using juce::Graphics::setOpacity before drawing the image onto the context. However it seems the image does not entirely disappear and i end up with a blotch stuck as in the screenshot of the PIP i made to repro (i faded out a white circle).
However if i use juce::Image::multiplyAllAlphas (which i want to avoid in my plugin) the image ends up totally fading out which is what i expect…
Here’s the PIP to reproduce the issue, clicking on the window retriggers the fade out. Am i missing something?
Cheers
(I have the issue with both juce 7 and 8)
/*******************************************************************************
The block below describes the properties of this PIP. A PIP is a short snippet
of code that can be read by the Projucer and used to generate a JUCE project.
BEGIN_JUCE_PIP_METADATA
name: BugTestPIP
dependencies: juce_core, juce_data_structures, juce_events, juce_graphics, juce_gui_basics
exporters: XCODE_MAC
moduleFlags: JUCE_STRICT_REFCOUNTEDPOINTER=1
type: Component
mainClass: MyComponent
END_JUCE_PIP_METADATA
*******************************************************************************/
#pragma once
//==============================================================================
class MyComponent : public juce::Component
, public juce::Timer
{
public:
//==============================================================================
MyComponent()
{
setSize (600, 400);
startTimer (timerInterval);
}
//==============================================================================
void paint (juce::Graphics& g) override
{
imageToRender.clear (imageToRender.getBounds());
juce::Graphics imageContext { imageToRender };
imageContext.setOpacity (0.9f);
// previousImage.multiplyAllAlphas (0.9f);
imageContext.drawImageAt (previousImage, 0, 0);
g.drawImageAt (imageToRender, 0, 0);
std::swap (imageToRender, previousImage);
}
void resized() override
{
initImage();
}
void mouseDown (const MouseEvent&) override
{
initImage();
}
//==============================================================================
void timerCallback() override
{
repaint();
}
private:
void initImage()
{
imageToRender = juce::Image (juce::Image::ARGB, getWidth(), getHeight(), true);
previousImage = juce::Image (juce::Image::ARGB, getWidth(), getHeight(), true);
juce::Graphics imageContext { previousImage };
imageContext.setOpacity (1.f);
const auto area = getLocalBounds();
const auto spotRadius = std::min (area.proportionOfWidth (0.5f), area.proportionOfHeight (0.5f));
const auto spotArea = juce::Rectangle<float> (0, 0, spotRadius, spotRadius).withCentre (area.getCentre().toFloat());
imageContext.setColour (Colours::white);
imageContext.fillRoundedRectangle (spotArea, spotArea.proportionOfHeight (0.5f));
}
private:
//==============================================================================
juce::Image imageToRender;
juce::Image previousImage;
static constexpr int timerInterval = 30;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MyComponent)
};

