I want to convert an SVG graphic to an OpenCV Mat object. Therefore the SVG graphic is loaded into a QSvgRenderer object and afterwards converted into a QImage object from which I use its raw data to create my final Mat object:
void scaleSvg(const cv::Mat &in, QSvgRenderer &svg, cv::Mat &out)
{
if (!svg.isValid())
{
return;
}
QImage image(in.cols, in.rows, QImage::Format_ARGB32);
// Get QPainter that paints to the image
QPainter painter(&image);
svg.render(&painter);
std::cout << "Image byte count: " << image.byteCount() << std::endl;
std::cout << "Image bits: " << (int*)image.constBits() << std::endl;
std::cout << "Image depth: " << image.depth() << std::endl;
uchar *data = new uchar[image.byteCount()];
memcpy(data, image.constBits(), image.byteCount());
out = cv::Mat(image.height(), image.width(), CV_8UC4, data, CV_AUTOSTEP);
std::cout << "New byte count: " << out.size() << std::endl;
std::cout << "New depth: " << out.depth() << std::endl;
std::cout << "First bit: " << out.data[0] << std::endl;
}
Unfortunately, I get a "memory access violation" error when writing my resulting object into a file:
std::cout << (int*)out.data << std::endl; // pointer can still be accessed without errors
cv::imwrite("scaled.png", out); // memory access error
The file which is being written gets to to size of 33 Bytes not more (header data only??). On the Internet there is some explanation of pointer ownership in cv::Mat and I thought it would be released after the last reference to it is release which should not be the case since "out" is a reference. Btw. another way to convert an SVG into a cv::Mat is always welcome. As OpenCV seem to do not support SVGs this looked like a simple way to get it done.