mirror of
https://github.com/iperov/DeepFaceLive
synced 2025-07-06 04:52:14 -07:00
xlib+
This commit is contained in:
parent
babe7e3215
commit
035029bdd6
4 changed files with 116 additions and 15 deletions
|
@ -1 +1,2 @@
|
||||||
from .ImageProcessor import ImageProcessor
|
from .ImageProcessor import ImageProcessor
|
||||||
|
from .misc import get_NHWC_shape
|
|
@ -4,7 +4,8 @@ from .core.widget import (BlockSignals, disable, enable, hide,
|
||||||
hide_and_disable, show, show_and_enable)
|
hide_and_disable, show, show_and_enable)
|
||||||
from .gui.from_file import (QIcon_from_file, QPixmap_from_file,
|
from .gui.from_file import (QIcon_from_file, QPixmap_from_file,
|
||||||
QXImage_from_file, QXPixmap_from_file)
|
QXImage_from_file, QXPixmap_from_file)
|
||||||
from .gui.from_np import QPixmap_from_np
|
from .gui.from_np import (QImage_ARGB32_from_buffer, QImage_BGR888_from_buffer,
|
||||||
|
QPixmap_from_np)
|
||||||
from .gui.QXImageSequence import QXImageSequence
|
from .gui.QXImageSequence import QXImageSequence
|
||||||
from .gui.QXPixmap import QXPixmap
|
from .gui.QXPixmap import QXPixmap
|
||||||
from .widgets.QXCheckBox import QXCheckBox
|
from .widgets.QXCheckBox import QXCheckBox
|
||||||
|
@ -22,6 +23,7 @@ from .widgets.QXLabel import QXLabel
|
||||||
from .widgets.QXLineEdit import QXLineEdit
|
from .widgets.QXLineEdit import QXLineEdit
|
||||||
from .widgets.QXMainApplication import QXMainApplication
|
from .widgets.QXMainApplication import QXMainApplication
|
||||||
from .widgets.QXMenuBar import QXMenuBar
|
from .widgets.QXMenuBar import QXMenuBar
|
||||||
|
from .widgets.QXOpenGLWidget import QXOpenGLWidget
|
||||||
from .widgets.QXProgressBar import QXProgressBar
|
from .widgets.QXProgressBar import QXProgressBar
|
||||||
from .widgets.QXPushButton import QXPushButton
|
from .widgets.QXPushButton import QXPushButton
|
||||||
from .widgets.QXRadioButton import QXRadioButton
|
from .widgets.QXRadioButton import QXRadioButton
|
||||||
|
|
|
@ -1,25 +1,72 @@
|
||||||
|
from typing import Union
|
||||||
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
from PyQt6.QtGui import *
|
from PyQt6.QtGui import *
|
||||||
from ...image import ImageProcessor
|
|
||||||
|
|
||||||
|
from ...image import ImageProcessor, get_NHWC_shape
|
||||||
|
|
||||||
|
_C_to_Format = {
|
||||||
|
1: QImage.Format.Format_Grayscale8,
|
||||||
|
3: QImage.Format.Format_BGR888,
|
||||||
|
4: QImage.Format.Format_ARGB32
|
||||||
|
}
|
||||||
|
|
||||||
def QPixmap_from_np(image : np.ndarray):
|
def QPixmap_from_np(image : np.ndarray):
|
||||||
ip = ImageProcessor(image).to_uint8()
|
"""
|
||||||
N,H,W,C = ip.get_dims()
|
constructs QPixmap from image np.ndarray
|
||||||
|
"""
|
||||||
|
if image.dtype != np.uint8:
|
||||||
|
raise ValueError('image.dtype must be np.uint8')
|
||||||
|
|
||||||
if N > 1:
|
N,H,W,C = get_NHWC_shape(image)
|
||||||
raise ValueError(f'N dim must be == 1')
|
if N != 1:
|
||||||
|
raise ValueError('image N must == 1')
|
||||||
if C == 1:
|
|
||||||
format = QImage.Format.Format_Grayscale8
|
format = _C_to_Format.get(C, None)
|
||||||
elif C == 3:
|
if format is None:
|
||||||
format = QImage.Format.Format_BGR888
|
|
||||||
elif C == 4:
|
|
||||||
format = QImage.Format.Format_ARGB32
|
|
||||||
else:
|
|
||||||
raise ValueError(f'Unsupported channels {C}')
|
raise ValueError(f'Unsupported channels {C}')
|
||||||
|
|
||||||
image = ip.get_image('HWC')
|
|
||||||
q_image = QImage(image.data, W, H, W*C, format)
|
q_image = QImage(image.data, W, H, W*C, format)
|
||||||
q_pixmap = QPixmap.fromImage(q_image)
|
q_pixmap = QPixmap.fromImage(q_image)
|
||||||
return q_pixmap
|
return q_pixmap
|
||||||
|
|
||||||
|
def QImage_from_np(image : np.ndarray):
|
||||||
|
"""
|
||||||
|
constructs QImage from image np.ndarray
|
||||||
|
|
||||||
|
given image must live the whole life cycle of QImage.
|
||||||
|
"""
|
||||||
|
if image.dtype != np.uint8:
|
||||||
|
raise ValueError('image.dtype must be np.uint8')
|
||||||
|
|
||||||
|
N,H,W,C = get_NHWC_shape(image)
|
||||||
|
if N != 1:
|
||||||
|
raise ValueError('image N must == 1')
|
||||||
|
format = _C_to_Format.get(C, None)
|
||||||
|
if format is None:
|
||||||
|
raise ValueError(f'Unsupported channels {C}')
|
||||||
|
return QImage(image.data, W, H, W*C, format)
|
||||||
|
|
||||||
|
def QImage_BGR888_from_buffer(buffer : Union[bytes, bytearray], width : int, height : int ):
|
||||||
|
|
||||||
|
"""
|
||||||
|
constructs QImage of BGR888 format from byte buffer with given width,height
|
||||||
|
|
||||||
|
given buffer must live the whole life cycle of QImage.
|
||||||
|
"""
|
||||||
|
if len(buffer) != width*height*3:
|
||||||
|
raise ValueError(f'Size of buffer must be width*height*3 == {width*height*3}')
|
||||||
|
|
||||||
|
return QImage(buffer, width, height, width*3, QImage.Format.Format_BGR888)
|
||||||
|
|
||||||
|
def QImage_ARGB32_from_buffer(buffer : Union[bytes, bytearray], width : int, height : int ):
|
||||||
|
|
||||||
|
"""
|
||||||
|
constructs QImage of ARGB32 format from byte buffer with given width,height
|
||||||
|
|
||||||
|
given buffer must live the whole life cycle of QImage.
|
||||||
|
"""
|
||||||
|
if len(buffer) != width*height*4:
|
||||||
|
raise ValueError(f'Size of buffer must be width*height*4 == {width*height*4}')
|
||||||
|
|
||||||
|
return QImage(buffer, width, height, width*3, QImage.Format.Format_ARGB32)
|
||||||
|
|
51
xlib/qt/widgets/QXOpenGLWidget.py
Normal file
51
xlib/qt/widgets/QXOpenGLWidget.py
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
from PyQt6.QtGui import *
|
||||||
|
from PyQt6.QtOpenGL import *
|
||||||
|
from PyQt6.QtOpenGLWidgets import *
|
||||||
|
from PyQt6.QtWidgets import *
|
||||||
|
|
||||||
|
from ._part_QXWidget import _part_QXWidget
|
||||||
|
|
||||||
|
_size_policy_from_str = {
|
||||||
|
'fixed' : QSizePolicy.Policy.Fixed,
|
||||||
|
'minimum' : QSizePolicy.Policy.Minimum,
|
||||||
|
'maximum' : QSizePolicy.Policy.Maximum,
|
||||||
|
'preferred' : QSizePolicy.Policy.Preferred,
|
||||||
|
'minimumexpanding' : QSizePolicy.Policy.MinimumExpanding,
|
||||||
|
'expanding' : QSizePolicy.Policy.Expanding,
|
||||||
|
'ignored' : QSizePolicy.Policy.Ignored,
|
||||||
|
}
|
||||||
|
|
||||||
|
class QXOpenGLWidget(QOpenGLWidget, _part_QXWidget):
|
||||||
|
def __init__(self,
|
||||||
|
font=None, tooltip_text=None,
|
||||||
|
size_policy=None,
|
||||||
|
minimum_size=None, minimum_width=None, minimum_height=None,
|
||||||
|
maximum_size=None, maximum_width=None, maximum_height=None,
|
||||||
|
fixed_size=None, fixed_width=None, fixed_height=None,
|
||||||
|
hided=False, enabled=True
|
||||||
|
):
|
||||||
|
|
||||||
|
super().__init__()
|
||||||
|
self._default_pal = QPalette( self.palette() )
|
||||||
|
|
||||||
|
if size_policy is not None:
|
||||||
|
x1, x2 = size_policy
|
||||||
|
if isinstance(x1, str):
|
||||||
|
x1 = _size_policy_from_str[x1.lower()]
|
||||||
|
if isinstance(x2, str):
|
||||||
|
x2 = _size_policy_from_str[x2.lower()]
|
||||||
|
size_policy = (x1, x2)
|
||||||
|
|
||||||
|
_part_QXWidget.__init__(self, font=font, tooltip_text=tooltip_text,
|
||||||
|
size_policy=size_policy,
|
||||||
|
minimum_size=minimum_size, minimum_width=minimum_width, minimum_height=minimum_height,
|
||||||
|
maximum_size=maximum_size, maximum_width=maximum_width, maximum_height=maximum_height,
|
||||||
|
fixed_size=fixed_size, fixed_width=fixed_width, fixed_height=fixed_height,
|
||||||
|
hided=hided, enabled=enabled )
|
||||||
|
def focusInEvent(self, ev : QFocusEvent):
|
||||||
|
super().focusInEvent(ev)
|
||||||
|
_part_QXWidget.focusInEvent(self, ev)
|
||||||
|
|
||||||
|
def resizeEvent(self, ev : QResizeEvent):
|
||||||
|
super().resizeEvent(ev)
|
||||||
|
_part_QXWidget.resizeEvent(self, ev)
|
Loading…
Add table
Add a link
Reference in a new issue