Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. [SOLVED]Access image pixels from QScript Engine
QtWS25 Last Chance

[SOLVED]Access image pixels from QScript Engine

Scheduled Pinned Locked Moved General and Desktop
qscriptengine
10 Posts 2 Posters 5.1k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • ealioneE Offline
    ealioneE Offline
    ealione
    wrote on last edited by ealione
    #1

    How can I get a pixmap inside my script and then, after modifying it, return it back to my main app so it can repaint the image?

    For example a simple case would be making the whole image black. I would have two public slots named something like getPixels() that returns ?, and setPixels(?). What would be the best variable type to use?

    1 Reply Last reply
    0
    • O Offline
      O Offline
      onek24
      wrote on last edited by onek24
      #2

      If you are using QPixmap, then you can convert your QPixmap to a QImage and iterate over each line using scanLine(). You will get a pointer to the first pixel in the line, you can go to the second one by incrementing your pointer. You can convert your modified QImage back to a QPixmap using QPixmap::fromImage().
      About the variable: scanline returns a uchar pointer. Afaik you can cast it into a QRgb pointer or manipulate it directly, whatever you prefer. It could look similar to that(for a Format_RGB32 Image):

      QImage image = pixmap.toImage();
      for(int i = 0; i < image.height(); ++i) // to get each line
      {
          QRgb *rgb = (QRgb*)image.scanLine(i); // get line at i
          for(int x = 0; x < image.width(); ++x) // iterate over each pixel in each line
          {
              *rgb = qRgb(qRed(color), qGreen(color), qBlue(color)); // manipulate the image
              ++rgb; // increment rgb to go to the next pixel
          }
      }
      

      I haven't testet the code so i don't know if it works, but the idea behind it is correct.

      1 Reply Last reply
      1
      • ealioneE Offline
        ealioneE Offline
        ealione
        wrote on last edited by
        #3

        Hi @onek24,
        I do not want to access pixel values of an image. I want to edit those values from inside a script that is run through the script engine.

        Regards.

        O 1 Reply Last reply
        0
        • ealioneE ealione

          Hi @onek24,
          I do not want to access pixel values of an image. I want to edit those values from inside a script that is run through the script engine.

          Regards.

          O Offline
          O Offline
          onek24
          wrote on last edited by onek24
          #4

          @ealione said:

          Hi @onek24,
          I do not want to access pixel values of an image. I want to edit those values from inside a script that is run through the script engine.

          Regards.

          Well, thats how you manipulate(edit) pixels from C++ using Qt. I haven't worked with the QScriptEngine yet so i'm not sure if i can help you with that. Maybe you could connect a signal with a slot in c++ which manipulates a pixel or a hole area? Afaik QScriptEngine can't work with QImages directly, but i might be wrong.

          1 Reply Last reply
          0
          • ealioneE Offline
            ealioneE Offline
            ealione
            wrote on last edited by
            #5

            One possible way could be having to functions, as an example:

            QList<int> MainWindow::getPixel(int x, int y)
            {
                 QColor tempColor;
                QList<int> pixelValues;
            
                tempColor = QColor(m_image2->pixel(x, y));
                pixelValues << tempColor.red();
                pixelValues << tempColor.green();
                pixelValues << tempColor.blue();
            
                return pixelValues;
            }
            
            void MainWindow::setPixel(int x, int y, QList<int> pVal)
            {
                m_image2->setPixel(x, y, qRgb(pVal[0], pVal[1], pVal[2]));
            
                m_item2->setPixmap(QPixmap::fromImage(*m_image2));
            }
            

            added as public slots: to your main class, or whatever class you want to make accessible to the ScriptEngine.
            This way you do not read all the values at once but it can still be useful.

            A second way could be encapsulating your data inside a QObject, which you later on make available to the ScriptEngine under a certain name.

            Thus I am marking this as solved, but if someone knows a better way or believes these solutions are not correct do say so.

            O 1 Reply Last reply
            0
            • ealioneE ealione

              One possible way could be having to functions, as an example:

              QList<int> MainWindow::getPixel(int x, int y)
              {
                   QColor tempColor;
                  QList<int> pixelValues;
              
                  tempColor = QColor(m_image2->pixel(x, y));
                  pixelValues << tempColor.red();
                  pixelValues << tempColor.green();
                  pixelValues << tempColor.blue();
              
                  return pixelValues;
              }
              
              void MainWindow::setPixel(int x, int y, QList<int> pVal)
              {
                  m_image2->setPixel(x, y, qRgb(pVal[0], pVal[1], pVal[2]));
              
                  m_item2->setPixmap(QPixmap::fromImage(*m_image2));
              }
              

              added as public slots: to your main class, or whatever class you want to make accessible to the ScriptEngine.
              This way you do not read all the values at once but it can still be useful.

              A second way could be encapsulating your data inside a QObject, which you later on make available to the ScriptEngine under a certain name.

              Thus I am marking this as solved, but if someone knows a better way or believes these solutions are not correct do say so.

              O Offline
              O Offline
              onek24
              wrote on last edited by onek24
              #6

              @ealione Thats correct, but thats way too heavy for larger manipulations... From the QtDocs:

              QImage::setPixel()

              Warning: This function is expensive due to the call of the internal detach() function called within; if performance is a concern, we recommend the use of scanLine() to access pixel data directly.

              QImage::pixel()

              Warning: This function is expensive when used for massive pixel manipulations.

              Also i would replace the QList<int> with a QRgb, if this is a possible variable-type for the ScriptEngine.

              1 Reply Last reply
              1
              • ealioneE Offline
                ealioneE Offline
                ealione
                wrote on last edited by ealione
                #7

                @onek24 the QRgb seems like a good idea, I will have to try.

                What other options are there except from those functions. Scanline cannot be used as its output can't be returned to the ScriptEngine (but maybe I should try again). Unless if you mean I should use something like this:

                QRgb *rowData = (QRgb*)m_image1.scanLine(row);
                QRgb pixelData = rowData[col];
                

                That produces the same result, I have not tested it to see of it is faster though.

                O 1 Reply Last reply
                0
                • ealioneE ealione

                  @onek24 the QRgb seems like a good idea, I will have to try.

                  What other options are there except from those functions. Scanline cannot be used as its output can't be returned to the ScriptEngine (but maybe I should try again). Unless if you mean I should use something like this:

                  QRgb *rowData = (QRgb*)m_image1.scanLine(row);
                  QRgb pixelData = rowData[col];
                  

                  That produces the same result, I have not tested it to see of it is faster though.

                  O Offline
                  O Offline
                  onek24
                  wrote on last edited by onek24
                  #8

                  @ealione said:

                  @onek24 the QRgb seems like a good idea, I will have to try.

                  What other options are there except from those functions. Scanline cannot be used as its output can't be returned to the ScriptEngine (but maybe I should try again). Unless if you mean I should use something like this:

                  QRgb *rowData = (QRgb*)m_image1.scanLine(row);
                  QRgb pixelData = rowData[col];
                  

                  That produces the same result, I have not tested it to see of it is faster though.

                  There are several methods, if there is a QRgb given like in my example, then you can use qRed, qGreen, qBlue to get the colors as integers.

                  QRgb *pointerToAPixel = ...;
                  int redValue = qRed(*pointerToAPixel);
                  int greenValue = qGreen(*pointerToAPixel);
                  int blueValue = qBlue(*pointerToAPixel);
                  

                  Also you could work with QColor:

                  // Just pass it the scanLine-value instead of converting the scanLine into a QRgb pointer
                  QColor color = QColor::fromRgb(*scanLine);
                  int redValue = color.red();
                  int greenValue = color.green();
                  int blueValue = color.blue();
                  
                  1 Reply Last reply
                  0
                  • ealioneE Offline
                    ealioneE Offline
                    ealione
                    wrote on last edited by ealione
                    #9

                    This is what I am doing. The whole issue from the start was that I had difficulties passing multidimensional data from and to my script.

                    I think that we are practically saying the same thing, its just that as you said, going about it the way I have (reading and writing individual pixels) is quite slow.

                    O 1 Reply Last reply
                    0
                    • ealioneE ealione

                      This is what I am doing. The whole issue from the start was that I had difficulties passing multidimensional data from and to my script.

                      I think that we are practically saying the same thing, its just that as you said, going about it the way I have (reading and writing individual pixels) is quite slow.

                      O Offline
                      O Offline
                      onek24
                      wrote on last edited by onek24
                      #10

                      @ealione I'm just saying that it's better to use scanLine than setPixel() or pixel() for larger manipulations. About the datatypes: QScriptEngine can pass or take QVariants which can be converted into QVariantList or QVariantMap. A QVariantList is just a QList<QVariant>. If you look at this example you will see that you can create custom Objects and register them so your ScriptEngine will know what they are. You could create a struct which contains the x-coordinate, the y-coordinate and a new red, blue and green value to set. Add each struct to a QVariantList and pass it to your slot which manipulates the image. Now iterate over each pixel on the image using scanLine(if you want) and set the new value if your list has a new value for the pixel. For the reading part: Same struct, read the x, y, red, green and blue into the struct, write the struct into a QVariantList for every pixel you want and then return it to your ScriptEngine.
                      Also you could use a QVector<int> (as mentioned in the example).

                      1 Reply Last reply
                      1

                      • Login

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • Users
                      • Groups
                      • Search
                      • Get Qt Extensions
                      • Unsolved