opencvgtkubuntu-20.04conan

Gtk error: Fatal error reading PNG image file


When I'm running my program and want to load an image to it, the window for selecting an image appears but shortly after the program crashes and I get an error:## Heading ##

Gtk:ERROR:../../../../gtk/gtkiconhelper.c:494:ensure_surface_for_gicon: assertion failed (error == NULL): Failed to load /usr/share/icons/Yaru/16x16/status/image-missing.png: Fatal error reading PNG image file: Invalid IHDR data (gdk-pixbuf-error-quark, 0)  
Bail out! Gtk:ERROR:../../../../gtk/gtkiconhelper.c:494:ensure_surface_for_gicon: assertion failed (error == NULL): Failed to load /usr/share/icons/Yaru/16x16/status/image-missing.png: Fatal error reading PNG image file: Invalid IHDR data (gdk-pixbuf-error-quark, 0)  
Aborted

I have tried to add unset GDK_PIXBUF_MODULEDIR and unset GDK_PIXBUF_MODULE_FILE to .bashrc and it worked for about 7 runs of the program when the error reapeared. Then I tried to run sudo update-mime-database /usr/share/mime but nothing changed. Someone mentioned that running in sudo mode solved the problem, but did nothing for me. The worst thing is that sometimes the program runs just fine. I start it a few times in a row and the error just doesn't appear to be manifesting.
Edit: I have a simple gui made in Qt that has a button an a QGraphicsView, and here are the snippets of the code that might be helpful. The mainwindow:

#include "mainwindow.h"
#include "./ui_mainwindow.h"

#include <iostream>
#include <QFileDialog>
#include <QMessageBox>
#include <QWidget>
#include <QTableWidget>
#include <QString>
#include <QCloseEvent>

#include "colorfilter.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    this->setFixedSize(800, 600);
    ui->wHidden->hide();

    connect(ui->pbUploadImage, &QPushButton::clicked, this, &MainWindow::uploadImage);
    connect(ui->pbShowLayer, &QPushButton::clicked, this, &MainWindow::exposeLayer);

}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::uploadImage()
{
    if(ui->imgView->scene())
        ui->imgView->scene()->clear();

    this->m_fName = QFileDialog::getOpenFileName(this, tr("Open Image"), "/home", tr("Image Files (*.png *.jpg *.bmp)"));
    if(this->m_fName.isEmpty())
        return;

    QPixmap pMap(this->m_fName);

    if (! ui->imgView->scene()) {
        qDebug() << "No Scene!";

        QGraphicsScene *scene = new QGraphicsScene(this);
        ui->imgView->setScene(scene);
    }

    ui->imgView->scene()->addPixmap(pMap);
    std::cout << m_fName .toStdString()<< std::endl;

}

void MainWindow::exposeLayer()
{
    if(this->m_fName.size() == 0){
        MainWindow::showMessage(this, "Please sellect an image first");
        return;
    }
    ColorFilter::Layer layer = ColorFilter::toLayer(ui->cbColor->currentText());
    auto cf = new ColorFilter(this->m_fName, layer);
    std::vector<QImage> images = cf->getImages();

    ui->wHidden->setVisible(true);
    QPixmap pMap(QPixmap::fromImage(images[0]));

    if(!ui->imgView->scene()){
        qDebug() << "No Scene!";

        QGraphicsScene *scene = new QGraphicsScene(this);
        ui->imgView->setScene(scene);
    }
    ui->imgView->scene()->addPixmap(pMap);
}

void MainWindow::closeEvent(QCloseEvent *event)
{
    for(auto w : this->openedWindows)
        w->close();
    event->accept();
}

void MainWindow::showMessage(QWidget *parent, QString message)
{
    QMessageBox *noData = new QMessageBox(parent);
    noData->setText(message);
    noData->show();
}

colorfilter:

#include "colorfilter.h"

#include <iostream>
#include <vector>
#include <QString>
#include <QDebug>
#include <QWidget>
#include <QLabel>

#include "opencv2/core.hpp"
#include "opencv2/imgcodecs.hpp"

ColorFilter::ColorFilter(QString &fName, ColorFilter::Layer layer):
    m_fName{fName}, m_layer{layer}
{}

std::vector<QImage> ColorFilter::getImages()
{
    cv::Mat image = cv::imread(this->m_fName.toStdString(), cv::IMREAD_COLOR);
    if(image.empty())
        qDebug() << "No image";
    std::vector<cv::Mat> newImages;
    if(this->m_layer == ColorFilter::Layer::SUPER)
        newImages = this->superImage(image);
    // else if(this->m_layer == ColorFilter::Layer::RED)
    //     newImages = this->superImage()

    std::vector<QImage> result;
    for(auto &im : newImages)
        result.push_back(this->cvMatToQImage(im));

    return result;
}

ColorFilter::Layer ColorFilter::toLayer(const QString &layer)
{
    std::unordered_map<QString, Layer> toLayer = {
        {"red", ColorFilter::Layer::RED},
        {"blue", ColorFilter::Layer::BLUE},
        {"green", ColorFilter::Layer::GREEN},
        {"superimposed", ColorFilter::Layer::SUPER}
    };
    auto it = toLayer.find(layer);
    if(it != toLayer.end())
        return it->second;
    return ColorFilter::Layer::UNDEFINED;
}

std::vector<cv::Mat> ColorFilter::superImage(const cv::Mat &image)
{
    std::vector<cv::Mat> alteredImages;
    cv::Mat tmp;

    for(int i = 0; i < 8; i++){
        tmp = image.clone();
        for(int n = 0; n < tmp.rows; n++)
        {
            cv::Vec3b *row = tmp.ptr<cv::Vec3b>(n);
            for(int m = 0; m < tmp.cols; m++){
                cv::Vec3b &pixel = row[m];
                // pixel[i] is uchar to represent values between 0 and 255
                tmp.ptr<cv::Vec3b>(n)[m][0] = (uchar)(((((int)pixel[0]) >> i) & 1)*255);
                tmp.ptr<cv::Vec3b>(n)[m][1] = (uchar)(((((int)pixel[1]) >> i) & 1)*255);
                tmp.ptr<cv::Vec3b>(n)[m][2] = (uchar)(((((int)pixel[2]) >> i) & 1)*255);
            }
        }
        alteredImages.push_back(tmp);
    }
    return alteredImages;
}

QImage ColorFilter::cvMatToQImage(const cv::Mat &image)
{
    if (image.type() == CV_8UC1) {
        // Grayscale image
        return QImage(image.data, image.cols, image.rows, image.step, QImage::Format_Grayscale8);
    } else if (image.type() == CV_8UC3) {
        // 3-channel color image (BGR format)
        // cv stores images in BGR format, but QImage expects RGB, that's why it it swapped
        return QImage(image.data, image.cols, image.rows, image.step, QImage::Format_RGB888).rgbSwapped();
    } else {
        qDebug() << "Unsupported cv::Mat format for QImage conversion";
        return QImage();
    }

}

Solution

  • The problem was in the conan installation of opencv library, once manually installed all the errors were gone.