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.
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
Thanks for the idea.
Best regards