QImage data array row-major or column-major order?
-
Hi all,
I am developing an application and It looks like I had a bug that comes from the fact that making a QImage off of a numpy array of shape (h,w) only works if the array is flattened in column-major order before being passed to QImage constructor.
h, w = arr.shape[0], arr.shape[1] arr = (255*arr).astype(np.uint8).flatten(order='F') img = QtGui.QImage( arr, w, h, h*np.nbytes[np.uint8], QtGui.QImage.Format_Indexed8)
I know the QPainter origin is the top left corner, however does bytePerLine mean the number of bytes per row or per column of my initial array?
-
where do you use bytePerLine in the code? I don't see it.
-
It appears they are using the following version of the overloaded QImage call
QtGui.QImage(uchar *data, int width, int height, int bytesPerLine, QImage::Format format, QImageCleanupFunction cleanupFunction = nullptr, void *cleanupInfo = nullptr)
Thus the h*np.nbytes[np.uint8] would be the bytesPerLine
That being said here is an augmented bit of documentation (https://doc.qt.io/qt-5/qimage.html#QImage-5) covering this function that I think will answer the basic question, cannot guarantee it will not raise additional questions though
This constructs an image with the given width, height and format, that uses an existing memory buffer, data. The width and height must be specified in pixels. The bytesPerLine specifies the number of bytes per line (stride). For information on Stride see: (https://medium.com/@oleg.shipitko/what-does-stride-mean-in-image-processing-bba158a72bcd)
The buffer must remain valid throughout the life of the QImage and all copies that have not been modified or otherwise detached from the original buffer. The image does not delete the buffer at destruction. You can provide a function pointer cleanupFunction along with an extra pointer cleanupInfo that will be called when the last copy is destroyed.
If format is an indexed color format, the image color table is initially empty and must be sufficiently expanded with setColorCount() or setColorTable() before the image is used.