Why does drawing an svg path to an Image result in pixelation?

If I draw the path directly to the screen, it’s smooth and perfect.

If I draw the path into an Image, and then copy the Image to the screen, it’s pixelated.

I’m using a Mac Retina. My understanding is that the pixels are twice as many as regular.

But even if I make the image twice the size, and apply an AffineTransform to the Graphics of scale(2.0f) so everything draws twice the size into the image, it’s still pixelated.

Try applying the transform to the Path first then draw the path on your Image.

Matt

Thank you. Tried that, didn’t work.

void drawHighResolutionPath(Graphics& g, const Path& path)
{
    const float scaleFactor = 2.0f;
    int imageWidth = originalWidth * scaleFactor;
    int imageHeight = originalHeight * scaleFactor;
    Image highResImage = Image (Image::ARGB, imageWidth, imageHeight, true);
    Graphics imageGraphics (highResImage);
    imageGraphics.addTransform (AffineTransform::scale (scaleFactor));
    imageGraphics.setColour (Colours::black);
    imageGraphics.fillPath (path);
    g.drawImageTransformed (highResImage, AffineTransform::scale (1.0f / scaleFactor));
}

You’re doing exactly this, right?
How exactly are you copying the image to the screen?

The only difference was in my last step, instead of using

g.drawImageTransformed (highResImage, AffineTransform::scale (1.0f / scaleFactor));

I was using:

g.drawImage(myImage, getLocalBounds().toFloat());

…which should essentially do the same thing, as my Image size was 2x the localBounds.

However, the solution seems to be related to the fact that my component doing the drawing is part of my mainComponent, and the main component can be scaled, so I was using it at 150%, which increases the actual pixel resolution of my Mac from 2.0 scaleFactor to 3.0 scaleFactor. And if I had my GUI at 200%, then the scaleFactor needs to be 4.0. The answer was located in this thread below, but the basic idea is this:

void paint (Graphics& g)
{
    auto scaleFactor = g.getInternalContext().getPhysicalPixelScaleFactor();
    auto imageBounds = getLocalBounds().toFloat() * scaleFactor;

    g.saveState();  // save the current Graphics state

    // create an image to draw into with the specifed dimensions
    myImage = Image(Image::ARGB, (int) imageBounds.getWidth(), (int) imageBounds.getHeight(), true);

    // create a new Graphics that will draw into myImage
    Graphics tmp (myImage);

    // add a transform so everything will be drawn at the size corresponding to the scaleFactor
    tmp.addTransform(AffineTransform::scale(scaleFactor));

    //***** do the drawing here ******//

    g.restoreState();   // restore graphics state

    // copy the image to the screen at the normal size
    g.drawImage(myImage, getLocalBounds().toFloat());
}