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. Sends the image as HTML and draws it on the canvas.
Forum Update on Monday, May 27th 2025

Sends the image as HTML and draws it on the canvas.

Scheduled Pinned Locked Moved Unsolved General and Desktop
6 Posts 2 Posters 303 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.
  • M Offline
    M Offline
    MyNameIsQt
    wrote on last edited by MyNameIsQt
    #1

    This program loads an image saved as a binary from a file and tries to draw the image on an html5 canvas through QWebEngineView.

    
    QImage m_pBkgndImage;
    
    #include <QWebEngineScript>
    bool CBackground::onDraw()
    {
           // m_pBkgndImage is QImage
       if(!m_pBkgndImage->isNull()){
    
            if (m_pBkgndImage->colorSpace().isValid()){
                m_pBkgndImage->convertToColorSpace(QColorSpace::SRgb);
            }
            
            QPoint point(0,0);
            point.rx() = m_bkgndHeader.Left;
            point.ry() = m_bkgndHeader.Top;
    
            QWebEngineView view;
            QString htmlPath = QFileInfo(__FILE__).dir().absolutePath() + "/canvas.html";
            view.load(QUrl::fromLocalFile(htmlPath));
    
            QWebChannel channel;
            QVariant imageVariant = QVariant::fromValue(*m_pBkgndImage);
    
            qDebug() << m_pBkgndImage->size() << " b3";  //  output correct value
            
            imageObject = new QObject();
            imageObject->setProperty("imageData", imageVariant);
    
            channel.registerObject("imageObject", imageObject);
    
            int imageSizeInBytes = m_pBkgndImage->bytesPerLine() * m_pBkgndImage->height();
    
            QByteArray imageDataArray(reinterpret_cast<const char*>(m_pBkgndImage->bits()), imageSizeInBytes);
            //view.page()->setWebChannel(&channel);
            qDebug() << "b4: " << imageDataArray.size(); // output correct value
            QString jsCode = QString("drawCanvas('%1');").arg(QString(imageDataArray.toBase64()));
    
            view.page()->runJavaScript(jsCode);
    
            delete imageObject;
    
            if(!m_pBkgndImage->isNull()){
                delete m_pBkgndImage;
                m_pBkgndImage = nullptr;
            }
    
            return true;
        } else {
            QMessageBox::information(nullptr, "Drawing Image", "Failed 412");
            return false;
        }
    
        return false;
    }
    
    
    /* canvas.js */
    function drawCanvas(imageData) {        
            var canvas = document.getElementById("myCanvas");
            var context = canvas.getContext("2d");
            context.fillStyle = "yellow";
            context.fillRect(0, 0, canvas.width, canvas.height);
            console.error("length "+imageData.length); // js: Uncaught TypeError: Cannot read properties of undefined (reading 'length')
    
            console.error("Image Data Length: " + (imageData ? imageData.length : "Undefined"));  // output "undefined"
    
            var img = new Image();
            img.src = "data:image/webp;base64," + imageData;
            img.onerror = function(){
                console.error("Image failed to load");  // output image failed to load
            };
    
            img.onload = function() {
                console.error("onload");
                context.drawImage(img, 0, 0);
                console.error("width: "+img.width);
                console.error("height: "+img.height);
            };
        }
    
    

    results is

    console.error("length "+imageData.length);
    js: Uncaught TypeError: Cannot read properties of undefined (reading 'length')
    

    As you can see, a problem arises. Naturally, the canvas is simply filled with yellow. But no image is drawn.

    context.fillStyle = "yellow";
    context.fillRect(0, 0, canvas.width, canvas.height);
    

    It appears to be a problem with the image data the program sent to js. How do I solve this?
    Thanks for reading.

    JonBJ 1 Reply Last reply
    0
    • M MyNameIsQt

      This program loads an image saved as a binary from a file and tries to draw the image on an html5 canvas through QWebEngineView.

      
      QImage m_pBkgndImage;
      
      #include <QWebEngineScript>
      bool CBackground::onDraw()
      {
             // m_pBkgndImage is QImage
         if(!m_pBkgndImage->isNull()){
      
              if (m_pBkgndImage->colorSpace().isValid()){
                  m_pBkgndImage->convertToColorSpace(QColorSpace::SRgb);
              }
              
              QPoint point(0,0);
              point.rx() = m_bkgndHeader.Left;
              point.ry() = m_bkgndHeader.Top;
      
              QWebEngineView view;
              QString htmlPath = QFileInfo(__FILE__).dir().absolutePath() + "/canvas.html";
              view.load(QUrl::fromLocalFile(htmlPath));
      
              QWebChannel channel;
              QVariant imageVariant = QVariant::fromValue(*m_pBkgndImage);
      
              qDebug() << m_pBkgndImage->size() << " b3";  //  output correct value
              
              imageObject = new QObject();
              imageObject->setProperty("imageData", imageVariant);
      
              channel.registerObject("imageObject", imageObject);
      
              int imageSizeInBytes = m_pBkgndImage->bytesPerLine() * m_pBkgndImage->height();
      
              QByteArray imageDataArray(reinterpret_cast<const char*>(m_pBkgndImage->bits()), imageSizeInBytes);
              //view.page()->setWebChannel(&channel);
              qDebug() << "b4: " << imageDataArray.size(); // output correct value
              QString jsCode = QString("drawCanvas('%1');").arg(QString(imageDataArray.toBase64()));
      
              view.page()->runJavaScript(jsCode);
      
              delete imageObject;
      
              if(!m_pBkgndImage->isNull()){
                  delete m_pBkgndImage;
                  m_pBkgndImage = nullptr;
              }
      
              return true;
          } else {
              QMessageBox::information(nullptr, "Drawing Image", "Failed 412");
              return false;
          }
      
          return false;
      }
      
      
      /* canvas.js */
      function drawCanvas(imageData) {        
              var canvas = document.getElementById("myCanvas");
              var context = canvas.getContext("2d");
              context.fillStyle = "yellow";
              context.fillRect(0, 0, canvas.width, canvas.height);
              console.error("length "+imageData.length); // js: Uncaught TypeError: Cannot read properties of undefined (reading 'length')
      
              console.error("Image Data Length: " + (imageData ? imageData.length : "Undefined"));  // output "undefined"
      
              var img = new Image();
              img.src = "data:image/webp;base64," + imageData;
              img.onerror = function(){
                  console.error("Image failed to load");  // output image failed to load
              };
      
              img.onload = function() {
                  console.error("onload");
                  context.drawImage(img, 0, 0);
                  console.error("width: "+img.width);
                  console.error("height: "+img.height);
              };
          }
      
      

      results is

      console.error("length "+imageData.length);
      js: Uncaught TypeError: Cannot read properties of undefined (reading 'length')
      

      As you can see, a problem arises. Naturally, the canvas is simply filled with yellow. But no image is drawn.

      context.fillStyle = "yellow";
      context.fillRect(0, 0, canvas.width, canvas.height);
      

      It appears to be a problem with the image data the program sent to js. How do I solve this?
      Thanks for reading.

      JonBJ Offline
      JonBJ Offline
      JonB
      wrote on last edited by JonB
      #2

      @MyNameIsQt
      I am unsure precisely why you get that error message from JS when trying to execute drawCanvas(imageData) via QString("drawCanvas('%1');").arg(QString(imageDataArray.toBase64())). Start by passing e.g. literal string "'hello'" instead and see if that arrives? Just maybe your base 64 string of a whole image is a very long string being passed and that causes a problem?? I don't know.

      Meanwhile, perhaps I am missing something, but you create a local QWebEngineView object in onDraw(). That will be destroyed on exit from this function. I don't know what you are trying to do here.

      M 1 Reply Last reply
      0
      • JonBJ JonB

        @MyNameIsQt
        I am unsure precisely why you get that error message from JS when trying to execute drawCanvas(imageData) via QString("drawCanvas('%1');").arg(QString(imageDataArray.toBase64())). Start by passing e.g. literal string "'hello'" instead and see if that arrives? Just maybe your base 64 string of a whole image is a very long string being passed and that causes a problem?? I don't know.

        Meanwhile, perhaps I am missing something, but you create a local QWebEngineView object in onDraw(). That will be destroyed on exit from this function. I don't know what you are trying to do here.

        M Offline
        M Offline
        MyNameIsQt
        wrote on last edited by
        #3

        @JonB

            // cpp
                QString jsCode = QString("drawCanvas('%1');").arg("Hello");
                view.page()->runJavaScript(jsCode);    
           
         // js
                function drawCanvas(text) {
               
                   console.error("text "+text); // undefined
               
                       var canvas = document.getElementById("myCanvas");       
                       var context = canvas.getContext("2d");       
                       context.fillStyle = "yellow";       
                       context.fillRect(0, 0, canvas.width, canvas.height);       
                       context.font="48px serif";       
                       context.fillText(text, 10, 50);  // nothing
        
        

        The problem seems to occur when sending data from cpp to js.
        thanks.

        JonBJ 1 Reply Last reply
        0
        • M MyNameIsQt

          @JonB

              // cpp
                  QString jsCode = QString("drawCanvas('%1');").arg("Hello");
                  view.page()->runJavaScript(jsCode);    
             
           // js
                  function drawCanvas(text) {
                 
                     console.error("text "+text); // undefined
                 
                         var canvas = document.getElementById("myCanvas");       
                         var context = canvas.getContext("2d");       
                         context.fillStyle = "yellow";       
                         context.fillRect(0, 0, canvas.width, canvas.height);       
                         context.font="48px serif";       
                         context.fillText(text, 10, 50);  // nothing
          
          

          The problem seems to occur when sending data from cpp to js.
          thanks.

          JonBJ Offline
          JonBJ Offline
          JonB
          wrote on last edited by JonB
          #4

          @MyNameIsQt
          Hmm, I don't know why. Try sending, say, just a number (42) this way instead of a string. Does that get through, so it's some string issue, or is every attempt to pass any argument unsuccessful?

          And although you, I & the rest of the world know that QString("drawCanvas('%1');").arg("Hello") really should be fine, since you are testing why don't you just test with QString jsCode = "drawCanvas(42);" so as to be 100,000% sure?

          M 1 Reply Last reply
          0
          • JonBJ JonB

            @MyNameIsQt
            Hmm, I don't know why. Try sending, say, just a number (42) this way instead of a string. Does that get through, so it's some string issue, or is every attempt to pass any argument unsuccessful?

            And although you, I & the rest of the world know that QString("drawCanvas('%1');").arg("Hello") really should be fine, since you are testing why don't you just test with QString jsCode = "drawCanvas(42);" so as to be 100,000% sure?

            M Offline
            M Offline
            MyNameIsQt
            wrote on last edited by
            #5

            @JonB
            I just tried your suggestion. And it still shows the same result. I'm thinking about other ways to pass arguments to js to see this problem more accurately.

            JonBJ 1 Reply Last reply
            0
            • M MyNameIsQt

              @JonB
              I just tried your suggestion. And it still shows the same result. I'm thinking about other ways to pass arguments to js to see this problem more accurately.

              JonBJ Offline
              JonBJ Offline
              JonB
              wrote on last edited by
              #6

              @MyNameIsQt
              I really don't know why this. It's not as though it cannot find the function drawCanvas() function definition (e.g. not loaded yet), as you get into that and the error message indicates it cannot see the text parameter. I am not a regular JS dev, but I did do QWebEnginePage::runJavaScript() in the past under Ubuntu and I remember it working fine.

              I have no idea whether the following could be in any way related. I still do not understand how you have a QWebEngineView as a local variable, waiting to go out of scope. And normally you don't call anything (e.g. runJavaScript()) to do anything until you know the page has finished loading. There is a void QWebEnginePage::loadFinished(bool ok) signal and/or window or document onload() in JS. You might try whether it's any different in any of these (presumably after changing the scope/lifetime of your QWebEngineView view; object).

              1 Reply Last reply
              0

              • Login

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