Building a Pixmap
-
wrote on 30 Jul 2022, 12:02 last edited by
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 -
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
Davidwrote on 30 Jul 2022, 12:17 last edited by@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. -
wrote on 30 Jul 2022, 13:08 last edited by
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.
-
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.
-
Hi,
How is the data organized in your internal structure ?
-
wrote on 31 Jul 2022, 08:56 last edited by Perdrix
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
-
Rather than going pixel by pixel, I would write a method that fills a memory block with the content of the vectors.
7/7