Painting into an image / Quality

Hi,

when I paint something into an image and get the image back to screen, the
result is not the same as if I’d painted directly to screen. The result is a little
more blurred. Is there a way to get exactly the same result like painting to screen?

So here are the results. Normal paintng on the left side, painting to an image on the
right side:
paint

Code:

void MainComponent::paint (juce::Graphics& g)
{
    // Left Part draws to Screen
    juce::Rectangle<float> r1(50, 50, 50, 50);
    paintKnob(g, r1);

    // Right Part draws into Image and copy Image back to Screen
    juce::Image img(juce::Image::ARGB, 50, 50, false);
    juce::Graphics gi(img);
    juce::Rectangle<float> r2(0, 0, 50, 50);
    paintKnob(gi, r2);
    g.drawImage(img, 120, 50, 50, 50, 0, 0, 50, 50);
}

void MainComponent::paintKnob(juce::Graphics& g, juce::Rectangle<float> r)
{
    g.fillAll(getLookAndFeel().findColour(juce::ResizableWindow::backgroundColourId));

    g.setColour(juce::Colours::grey);
    g.drawRect(r);

    g.setColour(juce::Colours::black);
    g.fillEllipse(r.reduced(5));

    g.setColour(juce::Colours::grey);
    g.fillEllipse(r.reduced(8));

    g.setColour(juce::Colours::lightgrey);
    g.fillEllipse(r.reduced(11));

    g.setColour(juce::Colours::black);
    g.drawLine(r.getCentreX(), r.getCentreY(), r.getX() + 16, r.getY() + 16, 3);
}

Try with:
g.setImageResamplingQuality(Graphics::highResamplingQuality);
before g.drawImage()

Generally, if the component and the image have the exact same size, the image should not be rescaled.

Use g.drawImageAt(img, 0, 0); to draw it as is.

The reason could be that the on screen painting has an higher resolution (like Mac retina or windows High dpi setting) so there are more physical pixels per logical pixel. You might wanna get the logical/physical pixel factor (there is a Juce api call for this) and multiply it with the pixel size of the image, and scale the coordinates for the drawing too.

2 Likes

g.getInternalContext().getPhysicalPixelScaleFactor() or something to that effect.

I assume this is all for demonstration only, but don’t do this for real. Creating the image in paint is expensive and this done in a few places will really hammer your cpu if repaints happen frequently.