The documentation of
QImage::QImage(uchar *data, int width, int height, Format format, QImageCleanupFunction cleanupFunction = Q_NULLPTR, void *cleanupInfo = Q_NULLPTR)
describes that the data, refered by parameter 'data', must be 32 bit aligned. http://doc.qt.io/qt-5/qimage.html#QImage-3 But it's at least unclear what is meant exactly. I assume, each pixel takes 32 bits. But that is not the case. Constructing an image like this is working:
uint8_t* rgb = new uint8_t[3 * height * width];
QImage Img(rgb, width, height, QImage::Format_RGB888);
But this is confusing. When I want to get the pixel values from the image, I thought I need to do this (since the data is 32 bit aligned and Qrgb is 32 bit):
QRgb*rawPixelData = (QRgb*) Img.bits();
for(uint32_t i = 0; i < (Img.width * Img.height); ++i)
{
qDebug() << "Red" << qRed(rawPixelData[i]);
qDebug() << "Green" << qGreen(rawPixelData[i]);
qDebug() << "Blue" << qBlue(rawPixelData[i]);
}
But this is not working (leads to a crash). So, I assume, the data is not 32bit aligned. So, isn't the data 32 bit aligned, or I'm understanding something wrong?
I assume that by the "data" they mean the array of bytes used. And by alignment they mean that the first byte of the array would be 32bit aligned and thus
data % 4
would always be 0. It is not the internal alignment of every pixel, just the alignment of the memory block that contains the pixel data.Furthermore,
bits()
returns a pointer to an unsigned byte, not a pointer to aQRgb
. AQRgb
is essentially just an integer:I suspect you are getting a crash because the raw data is "compacted". Meaning that if your image has only RGB and no alpha, it will use only 24bits or 3 bytes per pixel, because that would eliminate a 25% memory usage overhead. As a result, you are walking off the actual data and getting a crash.
You should try iterating it as
w * h * 3
unsigned chars and incrementing by 3 for each next pixel, and your rgb would be respectively the bytes ati, i+1, i+2
.It could probably work if your image format was RGBA.
And indeed if you bother to check the
byteCount
you'd realize that the amount of bytes used internally are the minimum amount for a given format: