CofeehousePy/deps/scikit-image/skimage/io/_plugins/q_color_mixer.py

343 lines
12 KiB
Python

# the module for the qt color_mixer plugin
from qtpy import QtCore
from qtpy.QtWidgets import (QWidget, QStackedWidget, QSlider, QGridLayout,
QLabel, QFrame, QComboBox, QRadioButton,
QPushButton)
from .util import ColorMixer
class IntelligentSlider(QWidget):
''' A slider that adds a 'name' attribute and calls a callback
with 'name' as an argument to the registered callback.
This allows you to create large groups of sliders in a loop,
but still keep track of the individual events
It also prints a label below the slider.
The range of the slider is hardcoded from zero - 1000,
but it supports a conversion factor so you can scale the results'''
def __init__(self, name, a, b, callback):
QWidget.__init__(self)
self.name = name
self.callback = callback
self.a = a
self.b = b
self.manually_triggered = False
self.slider = QSlider()
self.slider.setRange(0, 1000)
self.slider.setValue(500)
self.slider.valueChanged.connect(self.slider_changed)
self.name_label = QLabel()
self.name_label.setText(self.name)
self.name_label.setAlignment(QtCore.Qt.AlignCenter)
self.value_label = QLabel()
self.value_label.setText('%2.2f' % (self.slider.value() * self.a
+ self.b))
self.value_label.setAlignment(QtCore.Qt.AlignCenter)
self.layout = QGridLayout(self)
self.layout.addWidget(self.name_label, 0, 0)
self.layout.addWidget(self.slider, 1, 0, QtCore.Qt.AlignHCenter)
self.layout.addWidget(self.value_label, 2, 0)
# bind this to the valueChanged signal of the slider
def slider_changed(self, val):
val = self.val()
self.value_label.setText(str(val)[:4])
if not self.manually_triggered:
self.callback(self.name, val)
def set_conv_fac(self, a, b):
self.a = a
self.b = b
def set_value(self, val):
self.manually_triggered = True
self.slider.setValue(int((val - self.b) / self.a))
self.value_label.setText('%2.2f' % val)
self.manually_triggered = False
def val(self):
return self.slider.value() * self.a + self.b
class MixerPanel(QFrame):
'''A color mixer to hook up to an image.
You pass the image you the panel to operate on
and it operates on that image in place. You also
pass a callback to be called to trigger a refresh.
This callback is called every time the mixer modifies
your image.'''
def __init__(self, img):
QFrame.__init__(self)
# self.setFrameStyle(QFrame.Box | QFrame.Sunken)
self.img = img
self.mixer = ColorMixer(self.img)
self.callback = None
#---------------------------------------------------------------
# ComboBox
#---------------------------------------------------------------
self.combo_box_entries = ['RGB Color', 'HSV Color',
'Brightness/Contrast',
'Gamma',
'Gamma (Sigmoidal)']
self.combo_box = QComboBox()
for entry in self.combo_box_entries:
self.combo_box.addItem(entry)
self.combo_box.currentIndexChanged.connect(self.combo_box_changed)
#---------------------------------------------------------------
# RGB color sliders
#---------------------------------------------------------------
# radio buttons
self.rgb_add = QRadioButton('Additive')
self.rgb_mul = QRadioButton('Multiplicative')
self.rgb_mul.toggled.connect(self.rgb_radio_changed)
self.rgb_add.toggled.connect(self.rgb_radio_changed)
# sliders
rs = IntelligentSlider('R', 0.51, -255, self.rgb_changed)
gs = IntelligentSlider('G', 0.51, -255, self.rgb_changed)
bs = IntelligentSlider('B', 0.51, -255, self.rgb_changed)
self.rs = rs
self.gs = gs
self.bs = bs
self.rgb_widget = QWidget()
self.rgb_widget.layout = QGridLayout(self.rgb_widget)
self.rgb_widget.layout.addWidget(self.rgb_add, 0, 0, 1, 3)
self.rgb_widget.layout.addWidget(self.rgb_mul, 1, 0, 1, 3)
self.rgb_widget.layout.addWidget(self.rs, 2, 0)
self.rgb_widget.layout.addWidget(self.gs, 2, 1)
self.rgb_widget.layout.addWidget(self.bs, 2, 2)
#---------------------------------------------------------------
# HSV sliders
#---------------------------------------------------------------
# radio buttons
self.hsv_add = QRadioButton('Additive')
self.hsv_mul = QRadioButton('Multiplicative')
self.hsv_mul.toggled.connect(self.hsv_radio_changed)
self.hsv_mul.toggled.connect(self.hsv_radio_changed)
# sliders
hs = IntelligentSlider('H', 0.36, -180, self.hsv_changed)
ss = IntelligentSlider('S', 0.002, 0, self.hsv_changed)
vs = IntelligentSlider('V', 0.002, 0, self.hsv_changed)
self.hs = hs
self.ss = ss
self.vs = vs
self.hsv_widget = QWidget()
self.hsv_widget.layout = QGridLayout(self.hsv_widget)
self.hsv_widget.layout.addWidget(self.hsv_add, 0, 0, 1, 3)
self.hsv_widget.layout.addWidget(self.hsv_mul, 1, 0, 1, 3)
self.hsv_widget.layout.addWidget(self.hs, 2, 0)
self.hsv_widget.layout.addWidget(self.ss, 2, 1)
self.hsv_widget.layout.addWidget(self.vs, 2, 2)
#---------------------------------------------------------------
# Brightness/Contrast sliders
#---------------------------------------------------------------
# sliders
cont = IntelligentSlider('x', 0.002, 0, self.bright_changed)
bright = IntelligentSlider('+', 0.51, -255, self.bright_changed)
self.cont = cont
self.bright = bright
# layout
self.bright_widget = QWidget()
self.bright_widget.layout = QGridLayout(self.bright_widget)
self.bright_widget.layout.addWidget(self.cont, 0, 0)
self.bright_widget.layout.addWidget(self.bright, 0, 1)
#----------------------------------------------------------------------
# Gamma Slider
#----------------------------------------------------------------------
gamma = IntelligentSlider('gamma', 0.005, 0, self.gamma_changed)
self.gamma = gamma
# layout
self.gamma_widget = QWidget()
self.gamma_widget.layout = QGridLayout(self.gamma_widget)
self.gamma_widget.layout.addWidget(self.gamma, 0, 0)
#---------------------------------------------------------------
# Sigmoid Gamma sliders
#---------------------------------------------------------------
# sliders
alpha = IntelligentSlider('alpha', 0.011, 1, self.sig_gamma_changed)
beta = IntelligentSlider('beta', 0.012, 0, self.sig_gamma_changed)
self.a_gamma = alpha
self.b_gamma = beta
# layout
self.sig_gamma_widget = QWidget()
self.sig_gamma_widget.layout = QGridLayout(self.sig_gamma_widget)
self.sig_gamma_widget.layout.addWidget(self.a_gamma, 0, 0)
self.sig_gamma_widget.layout.addWidget(self.b_gamma, 0, 1)
#---------------------------------------------------------------
# Buttons
#---------------------------------------------------------------
self.commit_button = QPushButton('Commit')
self.commit_button.clicked.connect(self.commit_changes)
self.revert_button = QPushButton('Revert')
self.revert_button.clicked.connect(self.revert_changes)
#---------------------------------------------------------------
# Mixer Layout
#---------------------------------------------------------------
self.sliders = QStackedWidget()
self.sliders.addWidget(self.rgb_widget)
self.sliders.addWidget(self.hsv_widget)
self.sliders.addWidget(self.bright_widget)
self.sliders.addWidget(self.gamma_widget)
self.sliders.addWidget(self.sig_gamma_widget)
self.layout = QGridLayout(self)
self.layout.addWidget(self.combo_box, 0, 0)
self.layout.addWidget(self.sliders, 1, 0)
self.layout.addWidget(self.commit_button, 2, 0)
self.layout.addWidget(self.revert_button, 3, 0)
#---------------------------------------------------------------
# State Initialization
#---------------------------------------------------------------
self.combo_box.setCurrentIndex(0)
self.rgb_mul.setChecked(True)
self.hsv_mul.setChecked(True)
def set_callback(self, callback):
self.callback = callback
def combo_box_changed(self, index):
self.sliders.setCurrentIndex(index)
self.reset()
def rgb_radio_changed(self):
self.reset()
def hsv_radio_changed(self):
self.reset()
def reset(self):
self.reset_sliders()
self.mixer.set_to_stateimg()
if self.callback:
self.callback()
def reset_sliders(self):
# handle changing the conversion factors necessary
if self.rgb_add.isChecked():
self.rs.set_conv_fac(0.51, -255)
self.rs.set_value(0)
self.gs.set_conv_fac(0.51, -255)
self.gs.set_value(0)
self.bs.set_conv_fac(0.51, -255)
self.bs.set_value(0)
else:
self.rs.set_conv_fac(0.002, 0)
self.rs.set_value(1.)
self.gs.set_conv_fac(0.002, 0)
self.gs.set_value(1.)
self.bs.set_conv_fac(0.002, 0)
self.bs.set_value(1.)
self.hs.set_value(0)
if self.hsv_add.isChecked():
self.ss.set_conv_fac(0.002, -1)
self.ss.set_value(0)
self.vs.set_conv_fac(0.002, -1)
self.vs.set_value(0)
else:
self.ss.set_conv_fac(0.002, 0)
self.ss.set_value(1.)
self.vs.set_conv_fac(0.002, 0)
self.vs.set_value(1.)
self.bright.set_value(0)
self.cont.set_value(1.)
self.gamma.set_value(1)
self.a_gamma.set_value(1)
self.b_gamma.set_value(0.5)
def rgb_changed(self, name, val):
if name == 'R':
channel = self.mixer.RED
elif name == 'G':
channel = self.mixer.GREEN
else:
channel = self.mixer.BLUE
if self.rgb_mul.isChecked():
self.mixer.multiply(channel, val)
elif self.rgb_add.isChecked():
self.mixer.add(channel, val)
else:
pass
if self.callback:
self.callback()
def hsv_changed(self, name, val):
h = self.hs.val()
s = self.ss.val()
v = self.vs.val()
if self.hsv_mul.isChecked():
self.mixer.hsv_multiply(h, s, v)
elif self.hsv_add.isChecked():
self.mixer.hsv_add(h, s, v)
else:
pass
if self.callback:
self.callback()
def bright_changed(self, name, val):
b = self.bright.val()
c = self.cont.val()
self.mixer.brightness(c, b)
if self.callback:
self.callback()
def gamma_changed(self, name, val):
self.mixer.gamma(val)
if self.callback:
self.callback()
def sig_gamma_changed(self, name, val):
ag = self.a_gamma.val()
bg = self.b_gamma.val()
self.mixer.sigmoid_gamma(ag, bg)
if self.callback:
self.callback()
def commit_changes(self):
self.mixer.commit_changes()
self.reset_sliders()
def revert_changes(self):
self.mixer.revert()
self.reset_sliders()
if self.callback:
self.callback()