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. Building a Pixmap
QtWS25 Last Chance

Building a Pixmap

Scheduled Pinned Locked Moved Unsolved General and Desktop
qimage
7 Posts 3 Posters 1.4k 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.
  • PerdrixP Offline
    PerdrixP Offline
    Perdrix
    wrote on last edited by
    #1

    I have an image processing programme that holds the images in storage in its own format that are suited to what it does. Right now the images are displayed by converting them to an in storage 32 bit Windows bitmap.

    I'm in the process of converting from MFC /GDI to Qt (long task). It would seem that the obvious Qt class for displaying the images would be QPixmap, but I get the impression from the documentation that there's no way to access the internal data of a Pixmap as it is platform dependent (makes sense to me). So, I think I need to build a QImage (Format_RGB32) and then convert it.

    A simplified version of the code I use to populate the Windows bitmap looks like this:

                                    for (j = 0;j<m_lHeight;j++)
    				{
    					LPBYTE			lpOut;
    					LPRGBQUAD &		lpOutPixel = (LPRGBQUAD &)lpOut;
    
    					lpOut = GetPixelBase(0, j);
    					for (i = 0;i<m_lWidth;i++)
    					{
    						double			fRed, fGreen, fBlue;
    						pBitmap->GetPixel(i, j, fRed, fGreen, fBlue);
    
    						lpOutPixel->rgbRed		= std::min(std::max(0.0, fRed), 255.0);
    						lpOutPixel->rgbGreen	= std::min(std::max(0.0, fGreen), 255.0);
    						lpOutPixel->rgbBlue	= std::min(std::max(0.0, fBlue), 255.0);
    						lpOutPixel->rgbReserved	= 0;
    
    						lpOut += 4;
    					};
    				};
    

    Is the correct code as simple as:

                                    QImage image(m_lWidth, m_lHeight, QImage::FormatRGB32);
                                    for (j = 0;j<m_lHeight;j++)
    				{
    					QRgb value;
    					for (i = 0;i<m_lWidth;i++)
    					{
    						double			fRed, fGreen, fBlue;
    						pBitmap->GetPixel(i, j, fRed, fGreen, fBlue); /* My internal representation */
    
    						image.setPixel(i, j, 
                                                                QRgb(std::min(std::max(0.0, fRed), 255.0),
    						                        std::min(std::max(0.0, fGreen), 255.0),
    						                        std::min(std::max(0.0, fBlue), 255.0));
    					};
    				};
    

    Or would it be more efficient to iterate starting at scanline(0) and access the QRgb values in the QImage directly?

    Thank you
    David

    JonBJ 1 Reply Last reply
    0
    • PerdrixP Perdrix

      I have an image processing programme that holds the images in storage in its own format that are suited to what it does. Right now the images are displayed by converting them to an in storage 32 bit Windows bitmap.

      I'm in the process of converting from MFC /GDI to Qt (long task). It would seem that the obvious Qt class for displaying the images would be QPixmap, but I get the impression from the documentation that there's no way to access the internal data of a Pixmap as it is platform dependent (makes sense to me). So, I think I need to build a QImage (Format_RGB32) and then convert it.

      A simplified version of the code I use to populate the Windows bitmap looks like this:

                                      for (j = 0;j<m_lHeight;j++)
      				{
      					LPBYTE			lpOut;
      					LPRGBQUAD &		lpOutPixel = (LPRGBQUAD &)lpOut;
      
      					lpOut = GetPixelBase(0, j);
      					for (i = 0;i<m_lWidth;i++)
      					{
      						double			fRed, fGreen, fBlue;
      						pBitmap->GetPixel(i, j, fRed, fGreen, fBlue);
      
      						lpOutPixel->rgbRed		= std::min(std::max(0.0, fRed), 255.0);
      						lpOutPixel->rgbGreen	= std::min(std::max(0.0, fGreen), 255.0);
      						lpOutPixel->rgbBlue	= std::min(std::max(0.0, fBlue), 255.0);
      						lpOutPixel->rgbReserved	= 0;
      
      						lpOut += 4;
      					};
      				};
      

      Is the correct code as simple as:

                                      QImage image(m_lWidth, m_lHeight, QImage::FormatRGB32);
                                      for (j = 0;j<m_lHeight;j++)
      				{
      					QRgb value;
      					for (i = 0;i<m_lWidth;i++)
      					{
      						double			fRed, fGreen, fBlue;
      						pBitmap->GetPixel(i, j, fRed, fGreen, fBlue); /* My internal representation */
      
      						image.setPixel(i, j, 
                                                                  QRgb(std::min(std::max(0.0, fRed), 255.0),
      						                        std::min(std::max(0.0, fGreen), 255.0),
      						                        std::min(std::max(0.0, fBlue), 255.0));
      					};
      				};
      

      Or would it be more efficient to iterate starting at scanline(0) and access the QRgb values in the QImage directly?

      Thank you
      David

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

      @Perdrix
      For efficiency/simplicity, have a read of e.g. https://stackoverflow.com/questions/42958027/convert-gdi-plus-bitmap-to-qpixmap and https://doc.qt.io/qt-6/qimage.html#fromHBITMAP, etc.

      1 Reply Last reply
      0
      • PerdrixP Offline
        PerdrixP Offline
        Perdrix
        wrote on last edited by
        #3

        I think you misunderstand:

        The old code converted from my internal data format to a Windows HBITMAP.

        In order for my code to be portable, I no longer wish to use an HBITMAP but a Pixmap (via a QImage).

        D.

        JonBJ 1 Reply Last reply
        0
        • PerdrixP Perdrix

          I think you misunderstand:

          The old code converted from my internal data format to a Windows HBITMAP.

          In order for my code to be portable, I no longer wish to use an HBITMAP but a Pixmap (via a QImage).

          D.

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

          @Perdrix
          LOL, I didn't understand you wanted that!

          Or would it be more efficient to iterate starting at scanline(0) and access the QRgb values in the QImage directly?

          Then yes I believe so.

          1 Reply Last reply
          0
          • SGaistS Offline
            SGaistS Offline
            SGaist
            Lifetime Qt Champion
            wrote on last edited by
            #5

            Hi,

            How is the data organized in your internal structure ?

            Interested in AI ? www.idiap.ch
            Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

            1 Reply Last reply
            1
            • PerdrixP Offline
              PerdrixP Offline
              Perdrix
              wrote on last edited by Perdrix
              #6

              The internal image data is held in C++ classes, the data representation being in the form of three vectors (one for each of R, G, B). To be more explicit:

              template <typename TType>
              class CColorBitmapT : public CMemoryBitmap, public CColorBitmap
              {
              	// Omitted
              	private:
              	// Actual image data is held in another mono bitmap class of which there are three (one
                      // for each colour).  Data for each of these is stored as std:vector<TType> pixels;
                      // so effectively apart from the class wrapping you have:
                      //
                      std::vector<TType> redPixels;
                      std::vector<TType> greenPixels;
                      std::vector<TType> bluePixels;
              
              }
              typedef CColorBitmapT<std::uint8_t> C24BitColorBitmap;
              typedef CColorBitmapT<std::uint16_t> C48BitColorBitmap;
              typedef CColorBitmapT<std::uint32_t> C96BitColorBitmap;
              typedef CColorBitmapT<float> C96BitFloatColorBitmap;
              
              

              David

              1 Reply Last reply
              0
              • SGaistS Offline
                SGaistS Offline
                SGaist
                Lifetime Qt Champion
                wrote on last edited by
                #7

                Rather than going pixel by pixel, I would write a method that fills a memory block with the content of the vectors.

                Interested in AI ? www.idiap.ch
                Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                1 Reply Last reply
                3

                • Login

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