1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
|
from typing import Sequence
import numpy as np
from AnyQt.QtCore import Qt
from AnyQt.QtGui import QImage
def qimage_from_array(arr: np.ndarray) -> QImage:
"""
Create and return an QImage from a (N, M, C) uint8 array where C is 3 for
RGB and 4 for RGBA channels.
Parameters
----------
arr: (N, M C) uint8 array
Returns
-------
image: QImage
An QImage with size (M, N) in ARGB32 format format depending on `C`.
"""
h, w, c = arr.shape
if c == 4:
format = QImage.Format_ARGB32
elif c == 3:
format = QImage.Format_RGB32
else:
raise ValueError(f"Wrong number of channels (need 3 or 4, got {c}")
channels = arr.transpose((2, 0, 1))
img = QImage(w, h, QImage.Format_ARGB32)
img.fill(Qt.white)
if img.size().isEmpty():
return img
buffer = img.bits().asarray(w * h * 4)
view = np.frombuffer(buffer, np.uint32).reshape((h, w))
if format == QImage.Format_ARGB32:
view[:, :] = qrgba(*channels)
elif format == QImage.Format_RGB32:
view[:, :] = qrgb(*channels)
return img
def qimage_indexed_from_array(
arr: np.ndarray, colortable: Sequence[Sequence[int]]
) -> QImage:
arr = np.asarray(arr, dtype=np.uint8)
h, w = arr.shape
colortable = np.asarray(colortable, dtype=np.uint8)
ncolors, nchannels = colortable.shape
img = QImage(w, h, QImage.Format_Indexed8)
img.setColorCount(ncolors)
if nchannels == 4:
qrgb_ = qrgba
elif nchannels == 3:
qrgb_ = qrgb
else:
raise ValueError
for i, c in enumerate(colortable):
img.setColor(i, qrgb_(*c))
if img.size().isEmpty():
return img
buffer = img.bits().asarray(w * h)
view = np.frombuffer(buffer, np.uint8).reshape((h, w))
view[:, :] = arr
return img
def qrgb(
r: Sequence[int], g: Sequence[int], b: Sequence[int]
) -> Sequence[int]:
"""A vectorized `qRgb`."""
r, g, b = map(lambda a: np.asarray(a, dtype=np.uint32), (r, g, b))
return (0xff << 24) | ((r & 0xff) << 16) | ((g & 0xff) << 8) | (b & 0xff)
def qrgba(
r: Sequence[int], g: Sequence[int], b: Sequence[int], a: Sequence[int]
) -> Sequence[int]:
"""A vectorized `qRgba`."""
r, g, b, a = map(lambda a: np.asarray(a, dtype=np.uint32), (r, g, b, a))
return ((a & 0xff) << 24) | ((r & 0xff) << 16) | ((g & 0xff) << 8) | (b & 0xff)
|