Load SVG file from BinaryData

And here we go again for a new topic on how to load SVG files…

After having read all the related topics on the forum, I’ve come to understand that to load an svg file as a drawable object, we must to first create a BinaryData file, and then parse that BinaryData as a string into an xmlElement. And we should then use the createFromSVG static function of Drawable to obtain a pointer to a Drawable instance. i.e.

ScopedPointer svg_xml (XmlDocument::parse(BinaryData::myfile_svg));
if (svg_xml != nullptr ) {return Drawable::createFromSVG (*svg_xml);}

But when I do that I get an error that says

No matching constructor for initialization of ‘ScopedPointerjuce::XmlElement

This solution I found on that forum topic.

On this other forum topic I saw that doing the following should work too :

ScopedPointer svg (Drawable::createFromImageData (BinaryData::myfile_svg, BinaryData::myfile_svgSize));

But I get the same error :

No matching constructor for initialization of ‘ScopedPointerjuce::XmlElement

Could someone please explain to me what I am doing wrong?

I’d appreciate any help.

Romain P.

1 Like

First of all: ScopedPointer has been deprecated now for quite a while, so the examples you read must have been very old. Actually there is no need to create an xml element. Just do it like that:

// myDrawable will be of the type std::unique_ptr<Drawable>
auto myDrawable = juce::Drawable::createFromImageData (BinaryData::myfile_svg, BinaryData::myfile_svgSize);
4 Likes

The problem when I do it like that is that when I try to draw it, it produces the following error :

MainThread (1): signal SIGSEGV

The code I used to draw it is the following one, which I putted in the paint function of my editor :

Drawable* svg = Drawable::createFromImageData (BinaryData::selectPresetUp_svg, BinaryData::selectPresetUp_svgSize).get();
svg->draw(g, 1.0);

I also tried to use that Drawable in a DrawableButton but got the same error.

Obviously I am doing something wrong, could you point me out what that is?

Drawable::createFromImageData returns a std::unique_ptr and you’re grabbing it’s raw pointer via get(). the unique pointer get’s out-of-scope right after this line and the svg variable points to deallocated memory (aka a dangling pointer). Do it the following way:

const auto svg = Drawable::createFromImageData (BinaryData::selectPresetUp_svg, BinaryData::selectPresetUp_svgSize);
svg->draw(g, 1.0);

or even better hold a std::unique_pointer as a member of you class, do the loading in the constructor and then re-use them in your paint() instead of loading them on each paint.

2 Likes

Yeah, @PixelPacker already said the relevant things, I just want to give you the general advice to brush up your C++ basic skills regarding memory management a bit to better understand the code you are writing :slight_smile: I know C++ is a bit more level than other programing languages here, but especially when it comes to audio processing knowing where and how you manage your memory is mandatory to create stable running audio applications.

1 Like

Hi there,
i’ve been struggling previously as well. now figure it out.
You can use jucer to save the png file to binary, and output to your target platform.
And here are example code

FLButton.setImages(1, 1, 1,
ImageCache::getFromMemory(BinaryData::flseat_png,BinaryData::flseat_pngSize), 0.7f, Colours::transparentBlack,
ImageCache::getFromMemory(BinaryData::flseat_png,BinaryData::flseat_pngSize), 1.0f, Colours::transparentBlack,
ImageCache::getFromMemory(BinaryData::flseat_png,BinaryData::flseat_pngSize), 1.0f, getRandomBrightColour().withAlpha (0.8f),
0.5f);

… and with that answer, you’ve answered MY question! Bravo!