Search code examples
c++qtqgraphicsviewqgraphicssceneqimage

QImage::Format_mono to .png and QGraphicsScene


I have created a QImage of format QImage::Format_Mono. When I try and display the image to a QGraphicsView through a QGraphicsScene the view is unchanged. The QImage is loaded to the scene using a QPixmap produced through the QPixmap::fromImage() function. I also tried saving the QPixmap as a PNG/JPG/BMP using the save function as well to no avail. The basic code structure is as follows:

QGraphicsView *view = new QGraphicsView();
QGraphicsScene *scene = new QGraphicsScene();
view.setScene(scene);
QImage img(size,QImage::Format_Mono);
QVector<QRgb> v;
v.append(Qt::color0); // I have tried using black and white 
v.append(Qt::color1); // instead of color0 and 1 as well.
img.setColorTable(v);
// Do some stuff to populate the image using img.setPixel(c,r,bw)
// where bw is an index either 0 or 1 and c and r are within bounds
QPixmap p = QPixmap::fromImage(img);
p.save("mono.png");
scene->addPixmap(p);
// Code to display the view

If I instead make the image of QImage::Format_RGB888 and fill the pixels with either black or white the PNG/View displays appropriately.

How can I update my code to display the QImage in a QGraphicsView?


Solution

  • The error is that the Qt::GlobalColors (such as Qt::white or Qt::color0) are of type QColor, and not QRgb as expected. (QRgb is a typedef for unsigned int)

    You can convert a QColor to a QRgb by using the method QColor::rgb(), or directly create a QRgb using the global method qRgb(r,g,b). Following is a complete working example to illustrate, that displays (and saves as PNG) the very exact image whether mono is true or false.

    #include <QApplication>
    #include <QGraphicsScene>
    #include <QGraphicsView>
    
    int main(int argc, char **argv)
    {
        QApplication app(argc, argv);
    
        QGraphicsView *view = new QGraphicsView();
        QGraphicsScene *scene = new QGraphicsScene();
        view->setScene(scene);
    
        int W = 100;
        int H = 100;
        QImage img;
        uint color0 = qRgb(255,0,0);
        uint color1 = Qt::green.rgb();
        bool mono = true;
        if(mono)
        {
            img = QImage(QSize(W,H),QImage::Format_Mono);
            QVector<QRgb> v; v << color0 << color1;
            img.setColorTable(v);
            for(int i=0; i<W; i++)
            for(int j=0; j<H; j++)
            {
                uint index;
                if(j-(j/10)*10 > 5)
                    index = 0;
                else
                    index = 1;
                img.setPixel(i,j,index);
            }
        }
        else
        {
            img = QImage(QSize(W,H),QImage::Format_RGB888);
            for(int i=0; i<W; i++)
            for(int j=0; j<H; j++)
            {
                uint color;
                if(j-(j/10)*10 > 5)
                    color = color0;
                else
                    color = color1;
                img.setPixel(i,j,color);
            }
        }
    
        QPixmap p = QPixmap::fromImage(img);
        p.save("mono.png");
        scene->addPixmap(p);
        view->show();
    
        return app.exec();
    }