How to create Graphics array?

Hello,
it’s probably question more about C++ than about Juce. But I can’t find the solution.

I have array of Image, declared like that:
Image curvesIMG[3];

And now I need to have Graphics array to draw to my images. But of course declaring it like that:
Graphics curvesGraph[3];
gives me error.

I tried to define it in header with code:

MyClass() : curvesGraph{curvesIMG[0], curvesIMG[1], curvesIMG[2]}
{
}

But I get error: No viable conversion from 'juce::Image' to 'juce::Graphics'

So I started experimenting with std::vector<Graphics> curvesGraph, but for
push_back( Graphics(curvesIMG[0]) );
I get error: Call to deleted constructor of 'juce::Graphics'

So I tried:
curvesGraph.reserve(3);
curvesGraph.emplace_back(curvesIMG[0]);
But I get the same error.

So now I have no idea how to solve it. Could anyone help me?

Great thanks in advance,
Best Regards

Why are you using a Graphics context? Are you drawing into an Image? otherwise, we generally only access Graphics as it is passed into Componentpaint (Graphics& g)? You don’t store that, just use it. Maybe start out by explaining what you want to do, instead of how you are trying to do it. :slight_smile:

Hmm… thanks for your suggestion.

I am creating graphical equaliser, and all curves (Path) I stroke with Graphics curveGraph; to one Image allCurvesImg;, and then I use inside

Component::paint(Graphics& g)
{
    g.drawImageAt(allCurvesImg, x, y);
}

But now I found out it is not optimal, because even if I change only one EQ parameter, I need to call allCurvesImg.clear(allCurvesImg.getBounds()) and then stroke again all Paths. So I try to have all curves in separate Images, and then I can stroke only Paths that I really need but not all.

Of course the issue is much more complicated, but I explained the main issue as simple as possible.

Of course I could stroke Paths which I need inside Component::paint(), but actually I like the idea to keep them as Images and draw Images with g.drawImageAt(allCurvesImg, x, y);

The problem is, that the juce::Graphics constructor that takes an image is declared explicit. You could declare a simple helper class like this

template <size_t n>
class GraphicsArray : std::array<juce::Graphics, n>
{
public:

    GraphicsArray (std::array<juce::Image, n>& images)
        : GraphicsArray (images, std::make_index_sequence<n>())
    {}

private:
    // Calls the explicit constructor on each image in the array
    template <size_t... Is>
    GraphicsArray (std::array<juce::Image, n>& images, std::index_sequence<Is...>)
        : std::array<juce::Graphics, n> { (juce::Graphics (images[Is]))... }
    {}
};

Usage: In MyClass.h declare those two members

std::array<juce::Image, 3> curvesIMG;
GraphicsArray<3> curvesGraph { curvesIMG };

Now each array field of curvesGraph refers to the image with the same index, you can e.g. access curvesGraph[1] to write to curvesIMG[1] and so on.

Note 1: My solution is based on std::array rather than old school C arrays you used. I’d encourage you to use std::array in modern C++ code. You can still access it via [] like an old array.

Note 2: The helper class above is written down from memory and was not tested :wink:

Thanks for the idea.
Best regards