KernelPanic
KernelPanic

Reputation: 2432

QIcon null after creating it from .SVG file

I am working on a project, based on Embedded Linux and Qt 5.7. On filesystem, I have SVG image file and I want to transform it into PNG Image file. I've searched over internet and found several solutions for achieving such task here. However, I do not have SVG module installed and I was forced to use QIcon approach:

void ApplicationFlowDataManager::slotCreateQrCode(const QString& qrCodeContents)
{
    qDebug() << Q_FUNC_INFO
             << QImageWriter::supportedImageFormats();

    const QString GENERATED_QR_CODE_SVG=QString("/home/root/qrCodeGenerated.svg");
    const QString GENERATED_QR_CODE_PNG=QString("/home/root/qrCodeGenerated.png");

    qrcodegen::QrCode qr0=qrcodegen::QrCode::encodeText(qrCodeContents.toLocal8Bit().data(),
                                                        qrcodegen::QrCode::Ecc::MEDIUM);
    QString createdQrCode=QString::fromStdString(qr0.toSvgString(4));

    QFile qrCodeSVG(GENERATED_QR_CODE_SVG,
                    this);
    qrCodeSVG.open(QIODevice::WriteOnly|QIODevice::Text);
    qrCodeSVG.write(createdQrCode.toUtf8());
    qrCodeSVG.close();

    QImage imageQrCodePNG=QIcon(GENERATED_QR_CODE_SVG).pixmap(QSize(256,
                                                                    256)).toImage();    // <---- here is problem, QIcon is NULL and QImage has size QSize(0, 0) and therfore its save method returns false and no .PNG is created
    imageQrCodePNG.save(GENERATED_QR_CODE_PNG);
}   // slotCreateQrCode

The problem is created QIcon is NULL, like I described in problematic line of code. SVG file exists, I've 100x checked it. I've have also checked for low free space on partition, it is ok, I've checked /home/root/ permissions, they are not the problem since SVG file is created. The directory /home/root/ is not getting locked in any way, what is the problem?

P.S.: For QR Code handling, I am using Nayuki QR Code Generator Library.

Upvotes: 1

Views: 497

Answers (1)

eyllanesc
eyllanesc

Reputation: 244252

Explanation:

QIcon according to the type of file extension uses a QIconEngine that is provided by a plugin, in case the file has an .svg extension, try the plugin that handles that format that is provided by the Qt SVG module, so in your If you don't have that plugin since you don't have the module then the QIcon will be null.

Solution:

You must use the information from the getModule method of QrCode to do the painting manually:

#include <QtWidgets>

#include <QrCode.hpp>

static QImage slotCreateQrCode(const QString& qrCodeContents)
{
    qrcodegen::QrCode qr0=qrcodegen::QrCode::encodeText(qrCodeContents.toLocal8Bit().constData(),
                                                        qrcodegen::QrCode::Ecc::MEDIUM);

    const int s = qr0.getSize();
    const int margin = 1;
    QImage imageQrCodePNG((s + 2 * margin) * QSize(1, 1), QImage::Format_Mono);

    {
        QPainter painter(&imageQrCodePNG);
        painter.fillRect(imageQrCodePNG.rect(), Qt::white);
        painter.setPen(Qt::NoPen);
        painter.setBrush(Qt::black);
        for (int i = 0; i < s ; ++i)
        {
            for (int j = 0; j < s; ++j)
            {
                if(qr0.getModule(i, j))
                    painter.drawRect(i + margin, j + margin, 1, 1);
            }
        }

    }
    return imageQrCodePNG;
}   // slotCreateQrCode

int main(int argc, char *argv[]) {
    QApplication a(argc, argv);

    QImage image = slotCreateQrCode("Stack Overflow");

    const QSize size(512, 512);

    QLabel label;
    label.setPixmap(QPixmap::fromImage(image.scaled(size)));
    label.setFixedSize(size);
    label.show();

    return a.exec();
}

enter image description here

Upvotes: 3

Related Questions