support padded QImage
This commit is contained in:
parent
75654b8495
commit
9355ecf469
@ -1685,21 +1685,25 @@ def makeQImage(imgData, alpha=None, copy=True, transpose=True):
|
||||
def qimage_to_ndarray(qimg):
|
||||
img_ptr = qimg.bits()
|
||||
|
||||
if hasattr(img_ptr, 'setsize'): # PyQt sip.voidptr
|
||||
if img_ptr is None:
|
||||
raise ValueError("Null QImage not supported")
|
||||
|
||||
h, w = qimg.height(), qimg.width()
|
||||
bpl = qimg.bytesPerLine()
|
||||
depth = qimg.depth()
|
||||
logical_bpl = w * depth // 8
|
||||
|
||||
if QT_LIB.startswith('PyQt'):
|
||||
# sizeInBytes() was introduced in Qt 5.10
|
||||
# however PyQt5 5.12 will fail with:
|
||||
# "TypeError: QImage.sizeInBytes() is a private method"
|
||||
# note that sizeInBytes() works fine with:
|
||||
# PyQt5 5.15, PySide2 5.12, PySide2 5.15
|
||||
try:
|
||||
# 64-bits size
|
||||
nbytes = qimg.sizeInBytes()
|
||||
except (TypeError, AttributeError):
|
||||
# 32-bits size
|
||||
nbytes = qimg.byteCount()
|
||||
img_ptr.setsize(nbytes)
|
||||
img_ptr.setsize(h * bpl)
|
||||
|
||||
memory = np.frombuffer(img_ptr, dtype=np.ubyte).reshape((h, bpl))
|
||||
memory = memory[:, :logical_bpl]
|
||||
|
||||
depth = qimg.depth()
|
||||
if depth in (8, 24, 32):
|
||||
dtype = np.uint8
|
||||
nchan = depth // 8
|
||||
@ -1708,10 +1712,12 @@ def qimage_to_ndarray(qimg):
|
||||
nchan = depth // 16
|
||||
else:
|
||||
raise ValueError("Unsupported Image Type")
|
||||
shape = qimg.height(), qimg.width()
|
||||
|
||||
shape = h, w
|
||||
if nchan != 1:
|
||||
shape = shape + (nchan,)
|
||||
return np.frombuffer(img_ptr, dtype=dtype).reshape(shape)
|
||||
arr = memory.view(dtype).reshape(shape)
|
||||
return arr
|
||||
|
||||
|
||||
def imageToArray(img, copy=False, transpose=True):
|
||||
|
@ -9,6 +9,7 @@ import pytest
|
||||
from numpy.testing import assert_array_almost_equal
|
||||
|
||||
import pyqtgraph as pg
|
||||
from pyqtgraph.Qt import QtGui
|
||||
|
||||
np.random.seed(12345)
|
||||
|
||||
@ -340,3 +341,24 @@ def test_ndarray_from_qpolygonf():
|
||||
poly = pg.functions.create_qpolygonf(0)
|
||||
arr = pg.functions.ndarray_from_qpolygonf(poly)
|
||||
assert isinstance(arr, np.ndarray)
|
||||
|
||||
|
||||
def test_qimage_to_ndarray():
|
||||
# for QImages created w/o specifying bytesPerLine, Qt will pad
|
||||
# each line to a multiple of 4-bytes.
|
||||
# test that we can handle such QImages.
|
||||
h = 10
|
||||
|
||||
fmt = QtGui.QImage.Format.Format_RGB888
|
||||
for w in [5, 6, 7, 8]:
|
||||
qimg = QtGui.QImage(w, h, fmt)
|
||||
qimg.fill(0)
|
||||
arr = pg.functions.qimage_to_ndarray(qimg)
|
||||
assert arr.shape == (h, w, 3)
|
||||
|
||||
fmt = QtGui.QImage.Format.Format_Grayscale8
|
||||
for w in [5, 6, 7, 8]:
|
||||
qimg = QtGui.QImage(w, h, fmt)
|
||||
qimg.fill(0)
|
||||
arr = pg.functions.qimage_to_ndarray(qimg)
|
||||
assert arr.shape == (h, w)
|
||||
|
Loading…
x
Reference in New Issue
Block a user