def METHOD_NAME(image):
    """Convert a QImage to a numpy array.
    If QImage format is not Format_RGB888, Format_RGBA8888 or Format_ARGB32,
    it is first converted to one of this format depending on
    the presence of an alpha channel.
    The created numpy array is using a copy of the QImage data.
    :param QImage image: The QImage to convert.
    :return: The image array of RGB or RGBA channels of shape
        (height, width, channels (3 or 4))
    :rtype: numpy.ndarray of uint8
    """
    rgba8888 = getattr(qt.QImage, 'Format_RGBA8888', None)  # Only in Qt5
    # Convert to supported format if needed
    if image.format() not in (qt.QImage.Format_ARGB32,
                              qt.QImage.Format_RGB888,
                              rgba8888):
        if image.hasAlphaChannel():
            image = image.convertToFormat(
                rgba8888 if rgba8888 is not None else qt.QImage.Format_ARGB32)
        else:
            image = image.convertToFormat(qt.QImage.Format_RGB888)
    format_ = image.format()
    channels = 3 if format_ == qt.QImage.Format_RGB888 else 4
    ptr = image.bits()
    if qt.BINDING == 'PyQt5':
        ptr.setsize(image.byteCount())
    elif qt.BINDING == 'PyQt6':
        ptr.setsize(image.sizeInBytes())
    elif qt.BINDING == 'PySide6':
        ptr = ptr.tobytes()
    else:
        raise RuntimeError("Unsupported Qt binding: %s" % qt.BINDING)
    # Create an array view on QImage internal data
    view = _as_strided(
        numpy.frombuffer(ptr, dtype=numpy.uint8),
        shape=(image.height(), image.width(), channels),
        strides=(image.bytesPerLine(), channels, 1))
    if format_ == qt.QImage.Format_ARGB32:
        # Convert from ARGB to RGBA
        # Not a byte-ordered format: do care about endianness
        if sys.byteorder == 'little':  # BGRA -> RGBA
            view = view[:, :, (2, 1, 0, 3)]
        else:  # big endian: ARGB -> RGBA
            view = view[:, :, (1, 2, 3, 0)]
    # Format_RGB888 and Format_RGBA8888 do not need reshuffling channels:
    # They are byte-ordered and already in the right order
    return numpy.array(view, copy=True, order='C')