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

Change color palette of QImage



  • Hello,
    Is there a way to implement a palette of color for an RGB image (.bmp, .png).
    For instance I would like to change the green part of every pixel with a QSpinBox.
    In total I would have 3 boxes (one for red, one for green and one for blue), which can edit the colors of the pixels individually.
    I have already checked this post: https://forum.qt.io/topic/53104/change-the-colors-palette-for-images/3 but I'm not allowed to use this solution because the rules for this project were set by the professor.


  • Moderators

    @chmod
    you can do it by inspecting/manipulating each pixel's RGB32 value, e.g. via QImage::scanline():

    for (int y = 0; y < img.height(); ++y)
    {
        QImage img; // image with an (A)RGB image format
        QRgb *line = reinterpret_cast<QRgb*>(img.scanLine(y));
        for (int x = 0; x < img.width(); ++x)
        {
            QRgb pixelRgb = line[x];
            // use qGreen()/qRed()/qBlue() to get value, manipulate to slider values and set it to newColor
            QColor newColor(...);
            line[x] = newColor.rgb();
        }
    }
    

    But i am not sure if this is the effect you want in the end.
    But basically this is how you get and set rgb pixels. what value you set back is up to you then. E.g. you want to do some sort of color blending?

    What values are the sliders exactly controlling in the end? Each component from 0-255?



  • Thank you for your reply, I've found a solution.
    " What values are the sliders exactly controlling in the end? Each component from 0-255? " I have three horizontal slider (for r, g, b) the range of the sliders goes from -255 to 255.
    Here is an exemple/part of the code:

    /*****************************************************/
    /* INPUT: slider position                            */
    /* PROCESS: change of the red value of a pixel.      */
    /* OUTPUT:                                           */
    /*****************************************************/
    void MainWindow::on_horizontalSlider_sliderMoved(int position)
    {
        QColor var;
        for(int i = 0; i < img_2 -> size().width(); i++)
        {
            for(int j = 0; j < img_2 -> size().height(); j++)
            {
                config.setR(img -> pixelColor(i, j).red() + position);
                config.setV(ui -> horizontalSlider_2 -> value() + img -> pixelColor(i, j).green());
                config.setB(ui -> horizontalSlider_3 -> value() + img -> pixelColor(i, j).blue());
                var.setRed(config.getR());
                var.setGreen(config.getV());
                var.setBlue(config.getB());
                img_2 -> setPixelColor(i, j, var);
            }
        }
        px = QPixmap::fromImage(*img_2);
        scene_2 -> addPixmap(px);
        ui -> graphicsView_2 -> setScene(scene_2);
    }
    

    To get the desired result when moving a slider (e.g. the slider to change the red value, see code), this red slider needs to know the current value of the other 2 sliders, this is achieved by caching the values from the sliders in the members of a class (see config.set*()).
    As slot in the GUI of the three sliders I have used "sliderMoved" and the image changes in real time.
    Note that

    img -> pixelColor(i, j);
    

    is the color of the original image.


  • Moderators

    @chmod said in Change color palette of QImage:

    I have three horizontal slider (for r, g, b) the range of the sliders goes from -255 to 255.

    why a range from -255 to 255?!
    A color component can only be in the range of 0-255. But your code also allows negative values



  • @raven-worx
    That's right but if I take the current value of pixel[0][0] for example:
    pixel[0][0].red() = 6;
    pixel[0][0].green() = 245;
    pixel[0][0].blue() = 180;
    The default position of each slider is at 0 if I want to decrease the value of red I move the slider to the left. If the value that the slider returns is > 6 the value rests at 0 it would never go below 0.
    The same goes to green if I move the slider to the right to increase the value and the value returned by the slider is > 10 the value of green would never exceed 255.
    A range from -127 to 128 wouldn't be enough since a pixel holds a value of max 255 as you said.


  • Moderators

    @chmod
    for example

    ui -> horizontalSlider_2 -> value() + img -> pixelColor(i, j).green()

    could expand to

    -255 + 0

    = -255 ??



  • Yeah, okay that's right, but you gotta keep looking in my example. I'm using methods (Getter and Setter) to solve this problem, as you can see in my example I m using the methods config.setR/V/B and in these methods I have an If statement. For example:

    if(ui -> horizontalSlider_2 -> value() + img -> pixelColor(i, j).green() < 0)
            green = 0;
    

    So when

    ui -> horizontalSlider_2 -> value() + img -> pixelColor(i, j).green()  
    

    is -1 or -5 or -255, green will never go below 0.
    I'm sorry I explained badly and said it wrong in the previous reply.


  • Moderators

    @chmod
    just a small improvement (mostly for readability) you can write:

    qBound(0, ui -> horizontalSlider_2 -> value() + img -> pixelColor(i, j).green(), 255)
    

Log in to reply