def numpy_to_QImage(array, QImage_format=None):
    """
    Transform numpy array into QImage.
    Data copy is avoided if possible.
    The QImage.data attribute contain the underlying numpy array
    to prevent python freeing that memory while the image is in use.
    (same or a copy of the given array, if copy was needed )
    """
    if numpy.ndim(array) == 2:
        h, w = array.shape
        if (QImage_format is None) or (
                QImage_format is QImage.Format_Indexed8
        ):  # lent pour affichage sur QWidget par contre rapide pour QGlWidget
            qimage = QImage(
                numpy.require(array, numpy.uint8, "C").data,
                w,
                h,
                QImage.Format_Indexed8,
            )
            qimage.setColorTable(grayTable)
            qimage.data = array
            return qimage
        elif QImage_format is QImage.Format_RGB32:
            bgrx = numpy.require(
                array * 65793, numpy.uint32,
                "C")  # 0.7 a 0.9 msec (65793    = (1<<16)+(1<<8)+1)
            qimage = QImage(bgrx.data, w, h, QImage.Format_RGB32)
            qimage.data = (
                bgrx  # permet de garder un reference de l'image et lui eviter un destruction qui fait planter PySide2
            )
            return qimage
        elif QImage_format is QImage.Format_ARGB32:
            bgra = numpy.empty((h, w, 4), numpy.uint8, "C")  # 0.01 mec
            bgra[..., 0] = array
            bgra[..., 1] = array  # 0.38 msec
            bgra[..., 2] = array
            bgra[..., 3] = 255
            qimage = QImage(bgra.data, w, h, QImage.Format_ARGB32)
            qimage.data = bgra
            return qimage
    elif numpy.ndim(array) == 3:
        h, w, channels = array.shape
        if channels == 3:
            bgrx = numpy.empty((h, w, 4), numpy.uint8, "C")
            bgrx[..., :3] = array
            qimage = QImage(bgrx.data, w, h, QImage.Format_RGB32)
            qimage.data = bgrx
            return qimage
        elif channels == 4:
            bgrx = numpy.require(array, numpy.uint8, "C")
            qimage = QImage(bgrx.data, w, h, QImage.Format_ARGB32)
            qimage.data = bgrx
            return qimage
        else:
            raise ValueError(
                "Color images can expects the last dimension to contain exactly three (R,G,B) or four (R,G,B,A) channels"
            )
    else:
        raise ValueError("can only convert 2D or 3D arrays")