12#include <klocalizedstring.h>
47 return min +
static_cast<int>(qRound(
static_cast<qreal
>(max - min) *
value));
52 return static_cast<qreal
>(
value - min) /
static_cast<qreal
>(max - min);
58 , m_colorSpace(colorSpace)
60 , m_activeLevelsCurve(nullptr)
61 , m_channelsHistogram(nullptr)
62 , m_lightnessHistogram(nullptr)
74 m_page.spacer01->changeSize(0,
m_page.comboBoxChannel->sizeHint().height(),
75 QSizePolicy::Expanding, QSizePolicy::Fixed);
101 connect(
m_page.buttonScaleHistogramToFit, SIGNAL(clicked()),
m_page.widgetHistogram, SLOT(setScaleToFit()));
102 connect(
m_page.buttonScaleHistogramToCutLongPeaks, SIGNAL(clicked()),
m_page.widgetHistogram, SLOT(setScaleToCutLongPeaks()));
163 QMessageBox::warning(
this, i18nc(
"@title:window",
"Krita"), i18n(
"The current configuration was created for a different colorspace and cannot be used.\nThe channels will be reset."));
164 warnKrita <<
"WARNING: trying to load levels info with invalid number of channels!";
184 for (
int ch = 0; ch < filterConfig->
levelsCurves().size(); ++ch) {
192 m_page.buttonLogarithmicHistogram->setChecked(
true);
194 m_page.buttonLinearHistogram->setChecked(
true);
198 m_page.buttonLightnessMode->setChecked(
true);
201 m_page.buttonAllChannelsMode->setChecked(
true);
233 levelsCurve.resetAll();
242 if (
m_page.buttonAllChannelsMode->isChecked()) {
268 if (i < m_dev->colorSpace()->channels().
length()) {
298 m_page.spinBoxOutputBlackPoint,
m_page.spinBoxOutputWhitePoint);
300 if (
m_page.buttonLightnessMode->isChecked()) {
301 m_page.comboBoxChannel->hide();
302 m_page.containerAllChannels->hide();
304 m_page.comboBoxChannel->show();
305 m_page.containerAllChannels->show();
307 m_page.comboBoxChannel->setCurrentIndex(index);
316 QColor leftColor(Qt::black), rightColor(Qt::white);
317 if (
m_page.buttonAllChannelsMode->isChecked() &&
323 leftColor = Qt::black;
324 rightColor = channelIndex == 0 ? Qt::blue : (channelIndex == 1 ? Qt::green : Qt::red);
326 leftColor = Qt::white;
327 rightColor = channelIndex == 0 ? Qt::cyan : (channelIndex == 1 ? Qt::magenta : (channelIndex == 2 ? Qt::yellow : Qt::black));
334 }
else if (
m_page.buttonAllChannelsMode->isChecked() &&
337 leftColor = Qt::white;
338 rightColor = Qt::black;
340 m_page.sliderInputLevels->setHandleColor(0, leftColor);
342 m_page.sliderInputLevels->setHandleColor(2, rightColor);
343 m_page.sliderOutputLevels->setHandleColor(0, leftColor);
344 m_page.sliderOutputLevels->setHandleColor(1, rightColor);
357 if ((
m_page.buttonLightnessMode->isChecked() ||
361 m_page.buttonAutoLevels->setEnabled(
true);
365 m_page.buttonAutoLevels->setEnabled(
true);
367 m_page.buttonAutoLevels->setEnabled(
false);
390 if (keys.size() > 0) {
394 colorSpaces.append(colorSpace);
399 if (histograms.size() > 0) {
400 m_page.widgetHistogram->setup(histograms, colorSpaces, channels);
402 m_page.widgetHistogram->setDefaultColor(Qt::gray);
408 m_page.widgetHistogram->clearChannels();
410 if (
m_page.buttonLightnessMode->isChecked() ||
413 m_page.widgetHistogram->setChannel(0, 0);
424 channels.append(channelInfo.pixelIndex());
427 m_page.widgetHistogram->setChannels(channels, 1);
473 const int virtualChannel =
m_page.comboBoxChannel->itemData(index).toInt();
488 if (
value >=
m_page.spinBoxInputWhitePoint->value()) {
489 m_page.spinBoxInputBlackPoint->setValue(
m_page.spinBoxInputWhitePoint->value() - 1);
495 m_page.sliderInputLevels->setBlackPoint(normalizedValue);
501 if (value <= m_page.spinBoxInputBlackPoint->
value()) {
502 m_page.spinBoxInputWhitePoint->setValue(
m_page.spinBoxInputBlackPoint->value() + 1);
508 m_page.sliderInputLevels->setWhitePoint(normalizedValue);
525 m_page.sliderOutputLevels->setBlackPoint(normalizedValue);
534 m_page.sliderOutputLevels->setWhitePoint(normalizedValue);
592 if (
m_page.buttonLightnessMode->isChecked() ||
614 KoColor midtonesColor(outputColorsColorSpace);
621 autolevelsDialog->
setCaption(i18nc(
"@title:window",
"Auto Levels"));
623 autolevelsDialog->setAttribute(Qt::WA_DeleteOnClose);
624 connect(autolevelsDialog, &QDialog::rejected,
625 [
this, previousLevelsCurve]()
632 connect(autolevelsDialog, &QDialog::finished, [
this](){ setEnabled(
true); });
635 autolevelsDialog->setEnabled(
true);
637 autolevelsDialog->show();
638 autolevelsDialog->raise();
639 autolevelsDialog->activateWindow();
650 previousLevelsCurves.append(levelsCurve);
672 autolevelsDialog->
setCaption(i18nc(
"@title:window",
"Auto Levels"));
674 autolevelsDialog->setAttribute(Qt::WA_DeleteOnClose);
675 connect(autolevelsDialog, &QDialog::rejected,
676 [
this, previousLevelsCurves]()
688 connect(autolevelsDialog, &QDialog::finished, [
this](){ setEnabled(
true); });
691 autolevelsDialog->setEnabled(
true);
693 autolevelsDialog->show();
694 autolevelsDialog->raise();
695 autolevelsDialog->activateWindow();
700 if (e->type() == QEvent::StyleChange) {
701 m_page.spacer01->changeSize(0,
m_page.comboBoxChannel->sizeHint().height(),
702 QSizePolicy::Expanding, QSizePolicy::Fixed);
704 return QWidget::event(e);
713 if (
m_page.buttonLightnessMode->isChecked() ||
735 const qreal shadowsOutput = isCMYK ? 1.0 - highlightsNormalizedColor[0] : shadowsNormalizedColor[0];
736 const qreal highlightsOutput = isCMYK ? 1.0 - shadowsNormalizedColor[0] : highlightsNormalizedColor[0];
737 const qreal midtonesOutput = midtonesNormalizedColor[0];
743 {histogram, channel},
781 shadowsOutput.append(shadowsNormalizedColor[channelHistogram.channel]);
782 highlightsOutput.append(highlightsNormalizedColor[channelHistogram.channel]);
783 midtonesOutput.append(midtonesNormalizedColor[channelHistogram.channel]);
802 qreal minBlackPoint = 1.0;
803 qreal maxWhitePoint = 0.0;
805 minBlackPoint = qMin(levelsCurve.inputBlackPoint(), minBlackPoint);
806 maxWhitePoint = qMax(levelsCurve.inputWhitePoint(), maxWhitePoint);
809 levelsCurve.setInputBlackPoint(minBlackPoint);
810 levelsCurve.setInputWhitePoint(maxWhitePoint);
qreal length(const QPointF &vec)
float value(const T *src, size_t ch)
const KoID GrayAColorModelID("GRAYA", ki18n("Grayscale/Alpha"))
const KoID CMYKAColorModelID("CMYKA", ki18n("CMYK/Alpha"))
const KoID LABAColorModelID("LABA", ki18n("L*a*b*/Alpha"))
const KoID RGBAColorModelID("RGBA", ki18n("RGB/Alpha"))
connect(this, SIGNAL(optionsChanged()), this, SLOT(saveOptions()))
static KisResourcesInterfaceSP instance()
This class holds the parameters for a levels adjustment. It is modeled after KisCubicCurve and has si...
qreal outputBlackPoint() const
Get the output black point.
void setOutputBlackPoint(qreal newOutputBlackPoint)
Set the output black point.
qreal inputBlackPoint() const
Get the input black point.
void setOutputWhitePoint(qreal newOutputWhitePoint)
Set the output white point.
qreal inputGamma() const
Get the gamma value.
void setName(const QString &newName)
Set the name associated with this levels info object. This allows us to carry around a display name f...
void resetOutputLevels()
Resets the output levels only.
qreal inputWhitePoint() const
Get the input white point.
void setInputGamma(qreal newInputGamma)
Set the gamma value.
void setInputWhitePoint(qreal newInputWhitePoint)
Set the input white point.
void resetInputLevels()
Resets the input levels only (and gamma)
qreal outputWhitePoint() const
Get the output white point.
void setInputBlackPoint(qreal newInputBlackPoint)
Set the input black point.
void resetAll()
Resets the input and output levels (and gamma)
bool useLightnessMode() const
void setLevelsCurves(const QVector< KisLevelsCurve > &newLevelsCurves)
const KisLevelsCurve lightnessLevelsCurve() const
void setShowLogarithmicHistogram(bool newShowLogarithmicHistogram)
static KisLevelsCurve defaultLevelsCurve()
const QVector< KisLevelsCurve > levelsCurves() const
void setUseLightnessMode(bool newUseLightnessMode)
void setLightnessLevelsCurve(const KisLevelsCurve &newLightnessLevelsCurve)
bool showLogarithmicHistogram() const
QRect exactBounds() const
enumChannelValueType
enum to define the value of the channel
@ UINT8
use this for an unsigned integer 8bits channel
@ UINT16
use this for an integer 16bits channel
QList< KoChannelInfo * > channels
virtual KoID colorModelId() const =0
virtual quint32 channelCount() const =0
virtual KoID colorDepthId() const =0
virtual void normalisedChannelsValue(const quint8 *pixel, QVector< float > &channels) const =0
virtual void fromNormalisedChannelsValue(quint8 *pixel, const QVector< float > &values) const =0
KoColor convertedTo(const KoColorSpace *cs, KoColorConversionTransformation::Intent renderingIntent, KoColorConversionTransformation::ConversionFlags conversionFlags) const
void toQColor(QColor *c) const
a convenience method for the above.
A dialog base class with standard buttons and predefined layouts.
void setMainWidget(QWidget *widget)
virtual void setCaption(const QString &caption)
T get(const QString &id) const
QList< QString > keysCompatibleWith(const KoColorSpace *colorSpace, bool isStrict=false) const
returns a list, sorted by preference: higher preference comes first
static KoHistogramProducerFactoryRegistry * instance()
virtual KoHistogramProducer * generate()=0
Factory method, generates a new KoHistogramProducer.
KoChannelInfo::enumChannelValueType valueType() const
#define KIS_ASSERT_RECOVER(cond)
#define KIS_SAFE_ASSERT_RECOVER_RETURN(cond)
QString button(const QWheelEvent &ev)
QVector< KisLevelsCurve > adjustMonochromaticContrast(ChannelHistogram lightnessHistogram, QVector< ChannelHistogram > &channelsHistograms, qreal shadowsClipping, qreal highlightsClipping, qreal maximumInputBlackAndWhiteOffset, MidtonesAdjustmentMethod midtonesAdjustmentMethod, qreal midtonesAdjustmentAmount, const QVector< qreal > &outputBlackPoints, const QVector< qreal > &outputWhitePoints, const QVector< qreal > &outputMidtones)
Creates a KisLevelsCurve for every channel in "channelsHistograms". Computes the input black and whit...
QVector< KisLevelsCurve > adjustPerChannelContrast(QVector< ChannelHistogram > &channelsHistograms, qreal shadowsClipping, qreal highlightsClipping, qreal maximumInputBlackAndWhiteOffset, MidtonesAdjustmentMethod midtonesAdjustmentMethod, qreal midtonesAdjustmentAmount, const QVector< qreal > &outputBlackPoints, const QVector< qreal > &outputWhitePoints, const QVector< qreal > &outputMidtones)
Creates a KisLevelsCurve for every channel in "channelsHistograms". Computes the input black and whit...
@ MidtonesAdjustmentMethod_UseMedian
@ ShadowsAndHighlightsAdjustmentMethod_MonochromaticContrast
QIcon loadIcon(const QString &name)
QVector< VirtualChannelInfo > getVirtualChannels(const KoColorSpace *cs, int maxChannels, bool supportsLightness, bool supportsHue, bool supportsSaturation)
QColor blendColors(const QColor &c1, const QColor &c2, qreal r1)
Convenience class that associates a KisHistogram and a channel index. This is useful because setting ...
const KoColorSpace * colorSpace(const QString &colorModelId, const QString &colorDepthId, const KoColorProfile *profile)
static KoColorSpaceRegistry * instance()