Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

QImage converting to RGB and saving new image!



  • What would be best

    A. Convert image from RGBA to RGB -> Save it
    B. Make a new image with the size of the original image, paint the background black, then paint the original image over the new image -> save

    this is what i have so far

    This is the File Dialog to select image

    void MainWindow::on_BUTTON_SELECTIMAGE_MATRIX_clicked()
    {
        QString fileName = QFileDialog::getOpenFileName(this, tr("Open Image"), "c\\", tr("Image Files (*.png *.jpg *.bmp)"));
        ui->TEXT_IMG_PATH->setText(fileName);
    }
    

    then send the image to this function that would do the converting

    void MainWindow::imageHandler(QImage img)
    {
        QImage img2{img.size(), QImage::Format_RGB32};
        img2.save("test.jpg");
    }
    

  • Lifetime Qt Champion

    Hi
    I think convert
    https://doc.qt.io/qt-5/qimage.html#convertToFormat
    but since it returns a copy, the difference would not be
    that huge but you avoid a bitblt (drawing it)



  • @mrjj ty for that :) i'll try that! just a quick question! how do i get the image from MainWindow::on_BUTTON_SELECTIMAGE_MATRIX_clicked() to void MainWindow::imageHandler(QImage img)


  • Lifetime Qt Champion

    Hi,

    Use the path you got to construct a QImage and then call your other method with it.



  • @SGaist

    void MainWindow::on_BUTTON_SELECTIMAGE_MATRIX_clicked()
    {
        QString fileName = QFileDialog::getOpenFileName(this, tr("Open Image"), "c\\", tr("Image Files (*.png *.jpg *.bmp)"));
    
        ui->TEXT_IMG_PATH->setText(fileName);
    
        imageObject = new QImage();
        imageObject->load(fileName);
    
        if(!fileName.isEmpty())
        {
            imageHandler(imageObject);
        }
    }
    
    void MainWindow::imageHandler(QImage *img)
    {
        QImage img2{img->size(), QImage::Format_RGB32};
        img2.save("test.jpg");
    
            qDebug() << "Converting Complete";
    }
    

    Correct? the reason im asking is cause qDebug() << "Converting Complete"; this was fired! but i can't find the file :S



  • @Kris-Revi

    img2.save("test.jpg");
    but i can't find the file :S

    Then try saving it with an absolute path instead of relative to the current directory?
    Test the return result of the save()?



  • so i found the picture in the build folder! and uhm... it looks weird!

    ORIGINAL:
    Original

    and this is the copy from QImage (img2)
    Copy



  • i got it working! :) but now the question remains can this be done with Qimage (from my python script)

    # Shift the fucker arround to being RGB565
    self.final = [(r >> 3) << 11 | (g >> 2) << 5 | (b >> 3) for (r, g, b) in img.getdata() ]
    

    extracting R,G,B from the image and store them in an array that i can send off to my 32x32 Matrix for display :)



  • @Kris-Revi
    If just for image format conversion, QImage has predefined format for RGB565:

    QImage::Format_RGB16
    The image is stored using a 16-bit RGB format (5-6-5).

    So you can convert the image to RGB565 directly using QImage converting function:

    QImage newImage = img.convertToFormat(QImage::Format_RGB16);
    

    But if you just need those arrays, AFAIK, there's no such convenient function to exact R,G,B arrays like in python.
    You can write your own though.



  • @Bonnie Ty for that :) still trying to figure out a way to get the RGB colors of each pixel and store them in a List :/



  • @Kris-Revi
    That's not difficult in C++ at all.
    The simplest and safest but not most efficient way is to get every pixel and save the R,G,B

    int size = img.width() * img.height();
    QVector<int> R, G, B;
    R.reserve(size);
    G.reserve(size);
    B.reserve(size);
    for(int y = 0; y < img.height(); y++)
        for(int x = 0; x < img.width(); x++) {
            QRgb rgb = img.pixel(x, y);
            R.append(qRed(rgb));
            G.append(qGreen(rgb));
            B.append(qBlue(rgb));
        }
    

    You can optimize the code to be more efficient by directly iterating from img.constBits() if you want.



  • @Bonnie this is from my python PyQt5 script (that is tested and works)

    [6371, 2145, 2145, 2145, 2145, 2145, 2145, 2145, 2145, 2145, 2145, 2145, 2145, 2145, 2145, 2145, 2145, 2145, 2145, 2145, 2145, 2145, 2145, 2145, 2145, 2145, 2145, 2145, 2145, 2145, 2145, 6371, 2113, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2113, 2145, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2145, 2145, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2145, 2145, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2145, 2145, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 288, 704, 320, 96, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2145, 2145, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 352, 1536, 8064, 3456, 3584, 3488, 480, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2145, 2145, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 13349, 26219, 19912, 3456, 14275, 10081, 3360, 192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2145, 2145, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2273, 29678, 63359, 52761, 40339, 26218, 5760, 1504, 8800, 18432, 2048, 0, 0, 0, 0, 0, 0, 0, 0, 2145, 2145, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4258, 2113, 48631, 23210, 31663, 65471, 28140, 1376, 11072, 47168, 22528, 0, 0, 0, 0, 0, 0, 0, 0, 2145, 2145, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2147, 6, 42261, 8422, 16938, 65503, 59164, 13574, 832, 34880, 26624, 0, 0, 0, 0, 0, 0, 0, 0, 2145, 2145, 0, 0, 0, 0, 0, 0, 0, 0, 256, 704, 928, 3009, 2883, 27917, 4327, 21167, 59196, 56987, 32078, 2784, 26656, 20480, 0, 0, 0, 0, 0, 0, 0, 0, 2145, 2145, 0, 0, 0, 0, 0, 0, 32, 608, 3424, 3296, 3552, 3680, 5696, 3456, 992, 29838, 54906, 50680, 34000, 2752, 20512, 10240, 0, 0, 0, 0, 0, 0, 0, 0, 2145, 2145, 0, 0, 0, 0, 0, 64, 960, 3584, 3488, 3200, 5760, 5824, 5760, 5664, 3520, 5345, 34063, 44278, 25612, 672, 8512, 2048, 0, 0, 0, 0, 0, 0, 0, 0, 2145, 2145, 0, 0, 0, 0, 0, 672, 3520, 5728, 7936, 12259, 12195, 7969, 5824, 5728, 5600, 1312, 7233, 19847, 7618, 1280, 1216, 8512, 2048, 0, 0, 0, 0, 0, 0, 0, 2145, 2145, 0, 0, 0, 0, 128, 3200, 3552, 5728, 14211, 30700, 24553, 10114, 5824, 5728, 5632, 3456, 1088, 1408, 1760, 5696, 3456, 7040, 12352, 0, 0, 0, 0, 0, 0, 0, 2145, 2145, 0, 0, 0, 0, 384, 3296, 3520, 5728, 14180, 24553, 18374, 9985, 5792, 3648, 5600, 3456, 1120, 9379, 38769, 51032, 46710, 23691, 10464, 0, 0, 0, 0, 0, 0, 0, 2145, 2145, 0, 0, 0, 0, 480, 3296, 3488, 5664, 7841, 7937, 7905, 5760, 5696, 5632, 5568, 3392, 1088, 17479, 65535, 65535, 61245, 48567, 12645, 0, 0, 0, 0, 0, 0, 0, 2145, 2145, 0, 0, 0, 0, 416, 3200, 3424, 5568, 5632, 5632, 5664, 5632, 5600, 5536, 3424, 1248, 992, 19560, 65535, 65503, 59164, 50712, 19049, 0, 0, 0, 0, 0, 0, 0, 2145, 2145, 0, 0, 0, 0, 256, 960, 3296, 3392, 5504, 3456, 3456, 5504, 3456, 3392, 1248, 3168, 832, 25707, 65471, 61277, 54970, 46486, 21130, 0, 0, 0, 0, 0, 0, 0, 2145, 2145, 0, 0, 0, 0, 64, 672, 3040, 3200, 3296, 3328, 3328, 3328, 3296, 3232, 3168, 3008, 672, 31887, 59100, 52825, 48599, 38066, 14791, 0, 0, 0, 0, 0, 0, 0, 2145, 2145, 0, 0, 0, 0, 0, 256, 704, 2944, 3072, 3104, 3168, 3168, 3104, 3072, 2944, 768, 640, 29646, 44405, 44373, 38034, 27501, 6339, 0, 0, 0, 0, 0, 0, 0, 2145, 2145, 0, 0, 0, 0, 0, 0, 288, 576, 736, 2848, 2912, 2880, 2880, 768, 704, 640, 8708, 31727, 38034, 31727, 27469, 12710, 0, 0, 0, 0, 0, 0, 0, 0, 2145, 2145, 0, 0, 0, 0, 0, 0, 0, 224, 448, 544, 576, 576, 640, 608, 576, 10789, 21130, 29550, 25388, 23243, 14791, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2145, 2145, 0, 0, 0, 0, 0, 0, 0, 0, 96, 224, 352, 416, 416, 6563, 16936, 23211, 21130, 14886, 8676, 4545, 8547, 10468, 4096, 2048, 0, 0, 0, 0, 0, 0, 2145, 2145, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2113, 6371, 12646, 19017, 16872, 12678, 14791, 2433, 608, 896, 2753, 14823, 12483, 8192, 4096, 0, 0, 0, 0, 0, 2145, 2145, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2113, 6371, 4386, 4258, 10565, 14759, 12934, 7809, 14308, 3744, 17351, 48567, 31305, 20480, 2112, 128, 0, 0, 0, 2145, 2145, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 256, 6339, 8484, 21130, 57050, 26251, 9953, 16357, 16005, 65535, 61147, 33158, 23464, 865, 0, 0, 0, 2145, 2145, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 352, 2337, 4226, 16936, 54938, 65535, 57147, 9410, 12099, 7968, 36273, 56923, 40147, 29710, 2497, 0, 0, 0, 2145, 2145, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 480, 224, 10533, 46486, 61277, 63390, 65503, 46646, 7489, 5984, 7426, 19465, 23307, 17064, 192, 0, 0, 0, 2145, 2113, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 480, 4417, 31663, 50712, 54970, 59164, 61309, 65407, 23882, 5888, 5856, 1472, 3200, 736, 160, 0, 0, 0, 2113, 6371, 2145, 2145, 2145, 2145, 2145, 2145, 2145, 2145, 2145, 2145, 2177, 2401, 2657, 10885, 35889, 44405, 50744, 57019, 57051, 40658, 16165, 20422, 12131, 7617, 7553, 5057, 2241, 2145, 2145, 2145, 6371]
    

    and this is the C++ with the code snippet you gave me

    QVector(24, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 24, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 99, 74, 8, 49, 33, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 115, 247, 206, 156, 99, 16, 0, 33, 74, 8, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 8, 189, 90, 123, 255, 107, 0, 41, 189, 90, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 165, 33, 66, 255, 231, 49, 0, 140, 107, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 107, 16, 82, 231, 222, 123, 8, 107, 82, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 16, 8, 0, 115, 214, 198, 132, 8, 82, 41, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 16, 16, 16, 16, 8, 16, 132, 173, 99, 0, 33, 8, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0, 0, 8, 16, 24, 41, 41, 24, 16, 16, 16, 0, 24, 74, 24, 0, 0, 33, 8, 0, 0, 0, 0, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0, 8, 8, 16, 49, 115, 90, 33, 16, 16, 16, 8, 0, 0, 0, 16, 8, 24, 49, 0, 0, 0, 0, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0, 8, 8, 16, 49, 90, 66, 33, 16, 8, 16, 8, 0, 33, 148, 198, 181, 90, 41, 0, 0, 0, 0, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0, 8, 8, 16, 24, 24, 24, 16, 16, 16, 16, 8, 0, 66, 255, 255, 239, 189, 49, 0, 0, 0, 0, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0, 8, 8, 16, 16, 16, 16, 16, 16, 16, 8, 0, 0, 74, 255, 255, 231, 198, 74, 0, 0, 0, 0, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0, 0, 8, 8, 16, 8, 8, 16, 8, 8, 0, 8, 0, 99, 255, 239, 214, 181, 82, 0, 0, 0, 0, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 0, 123, 231, 206, 189, 148, 57, 0, 0, 0, 0, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8, 0, 0, 115, 173, 173, 148, 107, 24, 0, 0, 0, 0, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 0, 0, 0, 33, 123, 148, 123, 107, 49, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 82, 115, 99, 90, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 66, 90, 82, 57, 33, 16, 33, 41, 16, 8, 0, 0, 0, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 24, 49, 74, 66, 49, 57, 8, 0, 0, 8, 57, 49, 33, 16, 0, 0, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 24, 16, 16, 41, 57, 49, 24, 49, 8, 66, 189, 123, 82, 8, 0, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 33, 82, 222, 99, 33, 57, 57, 255, 239, 132, 90, 0, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 16, 66, 214, 255, 222, 33, 41, 24, 140, 222, 156, 115, 8, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 181, 239, 247, 255, 181, 24, 16, 24, 74, 90, 66, 0, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 123, 198, 214, 231, 239, 255, 90, 16, 16, 0, 8, 0, 0, 0, 0, 0, 8, 24, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 41, 140, 173, 198, 222, 222, 156, 57, 74, 41, 24, 24, 16, 8, 8, 8, 8, 24)
    

    i loaded the same picture! why are they different?



  • @Kris-Revi
    I'm sure that what you have is a RGB value array, not R,G,B arrays. :)
    So you need the iterating way.
    But this way you need to know the detailed format and decide the byte size of every pixel first.
    For example, a RGB565 image need 16bits for every pixel, so we should use quint16 type to read:

    QVector<quint16> RGB565;
    RGB565.reserve(img.width() * img.height());
    for(int y = 0; y < img.height(); y++) {
        const quint16 *line = reinterpret_cast<const quint16*>(img.constScanLine(y));
        for(int x = 0; x < img.width(); x++)
            RGB565 << *(line++);
    }
    

    If the image is a RGB32 format image, then the type should be changed to quint32.
    If it is RGB24, then it will be more complicated...



  • @Bonnie said in QImage converting to RGB and saving new image!:

    QVector<quint16> RGB565;
    RGB565.reserve(img.width() * img.height());
    for(int y = 0; y < img.height(); y++) {
    const quint16 line = reinterpret_cast<const quint16>(img.constScanLine(y));
    for(int x = 0; x < img.width(); x++)
    RGB565 << *(line++);
    }

    ty for that one m8 :) so just to clarify

    every image that comes in gets copied and made into 16bit (5-6-5) so it will ALWAYS be 16bit :)

    // ================================================= //
    FINAL AND WORKING CODE FOR EVERYONE WHO IS INTERESSTED
    // ================================================= //

    void MainWindow::imageHandler(QImage *img)
    {
        QImage img2{img->size(), QImage::Format_RGB16}; // The image is stored using a 16-bit RGB format (5-6-5).
        img2.fill(QColor(Qt::black).rgb());             // Fill the new image with a black background (needs to be filled to get the correct color data)
        QPainter painter(&img2);                        // Prepare new image for painting
        painter.drawImage(0, 0, *img);                  // Paint the original image onto the new image
        img2.save("./MatrixImages/test.jpg");           // Save that fucker and lets move on
    
        // Get the color 16bit (5-6-5) color data and put it in a QVector and prepare for sending to ESP32
        QVector<quint16> RGB565;
        RGB565.reserve(img2.width() * img2.height());
        for(int y = 0; y < img2.height(); y++) {
            const quint16 *line = reinterpret_cast<const quint16*>(img2.constScanLine(y));
            for(int x = 0; x < img2.width(); x++)
                RGB565 << *(line++);
        }
    
        qDebug() << "[IMAGEHANDLER][INFO] Converting Complete";
    }
    

Log in to reply