Krita Source Code Documentation
Loading...
Searching...
No Matches
histogramdockerwidget.cpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2016 Eugene Ingerman <geneing at gmail dot com>
3 *
4 * SPDX-License-Identifier: LGPL-2.0-or-later
5 */
6
8
9#include <QThread>
10#include <limits>
11#include <algorithm>
12#include <QTime>
13#include <QPainter>
14#include <QPainterPath>
15#include <functional>
16
17#include "KoChannelInfo.h"
18#include "KisViewManager.h"
19#include "kis_canvas2.h"
20
21
22
23HistogramDockerWidget::HistogramDockerWidget(QWidget *parent, const char *name, Qt::WindowFlags f)
24 : KisWidgetWithIdleTask<QLabel>(parent, f)
25{
26 setObjectName(name);
27 qRegisterMetaType<HistogramData>();
28}
29
33
40
42{
44
45 return
46 canvas->viewManager()->idleTasksManager()->
47 addIdleTaskWithGuard([this](KisImageSP image) {
50
51 connect(strategy, SIGNAL(computationResultReady(HistogramData)), this, SLOT(receiveNewHistogram(HistogramData)));
52
53 return strategy;
54 });
55}
56
62
63void HistogramDockerWidget::paintEvent(QPaintEvent *event)
64{
65 if (m_colorSpace && !m_histogramData.empty()) {
66 int nBins = m_histogramData.at(0).size();
67 const KoColorSpace* cs = m_colorSpace;
68
69 QLabel::paintEvent(event);
70 QPainter painter(this);
71 painter.fillRect(0, 0, this->width(), this->height(), this->palette().dark().color());
72 painter.setPen(this->palette().light().color());
73
74 const int NGRID = 4;
75 for (int i = 0; i <= NGRID; ++i) {
76 painter.drawLine(this->width()*i / NGRID, 0., this->width()*i / NGRID, this->height());
77 painter.drawLine(0., this->height()*i / NGRID, this->width(), this->height()*i / NGRID);
78 }
79
80 unsigned int nChannels = cs->channelCount();
81 const QList<KoChannelInfo *> channels = cs->channels();
82 unsigned int highest = 0;
83 //find the most populous bin in the histogram to scale it properly
84 for (int chan = 0; chan < channels.size(); chan++) {
85 if (channels.at(chan)->channelType() != KoChannelInfo::ALPHA) {
86 std::vector<quint32> histogramTemp = m_histogramData.at(chan);
87 //use 98th percentile, rather than max for better visual appearance
88 int nthPercentile = 2 * histogramTemp.size() / 100;
89 //unsigned int max = *std::max_element(m_histogramData.at(chan).begin(),m_histogramData.at(chan).end());
90 std::nth_element(histogramTemp.begin(),
91 histogramTemp.begin() + nthPercentile, histogramTemp.end(), std::greater<int>());
92 unsigned int max = *(histogramTemp.begin() + nthPercentile);
93
94 highest = std::max(max, highest);
95 }
96 }
97
98 painter.setWindow(QRect(-1, 0, nBins + 1, highest));
99 painter.setCompositionMode(QPainter::CompositionMode_Plus);
100
101 for (int chan = 0; chan < (int)nChannels; chan++) {
102 if (channels.at(chan)->channelType() != KoChannelInfo::ALPHA) {
103 QColor color = channels.at(chan)->color();
104
105 //special handling of grayscale color spaces. can't use color returned above.
106 if(cs->colorChannelCount()==1){
107 color = QColor(Qt::gray);
108 }
109
110 QColor fill_color = color;
111 fill_color.setAlphaF(.25);
112 painter.setBrush(fill_color);
113 QPen pen = QPen(color);
114 pen.setWidth(0);
115 painter.setPen(pen);
116
117 if (m_smoothHistogram) {
118 QPainterPath path;
119 path.moveTo(QPointF(-1, highest));
120 for (qint32 i = 0; i < nBins; ++i) {
121 float v = std::max((float)highest - m_histogramData[chan][i], 0.f);
122 path.lineTo(QPointF(i, v));
123
124 }
125 path.lineTo(QPointF(nBins + 1, highest));
126 path.closeSubpath();
127 painter.drawPath(path);
128 } else {
129 pen.setWidth(1);
130 painter.setPen(pen);
131 for (qint32 i = 0; i < nBins; ++i) {
132 float v = std::max((float)highest - m_histogramData[chan][i], 0.f);
133 painter.drawLine(QPointF(i, highest), QPointF(i, v));
134 }
135 }
136 }
137 }
138 }
139}
qreal v
connect(this, SIGNAL(optionsChanged()), this, SLOT(saveOptions()))
KisIdleTasksManager::TaskGuard registerIdleTask(KisCanvas2 *canvas) override
const KoColorSpace * m_colorSpace
void receiveNewHistogram(HistogramData data)
void paintEvent(QPaintEvent *event) override
HistogramDockerWidget(QWidget *parent=0, const char *name=0, Qt::WindowFlags f=Qt::WindowFlags())
KisViewManager * viewManager() const
KisIdleTasksManager * idleTasksManager()
@ ALPHA
The channel represents the opacity of a pixel.
QList< KoChannelInfo * > channels
virtual quint32 channelCount() const =0
virtual quint32 colorChannelCount() const =0
#define KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(cond, val)
Definition kis_assert.h:129
rgba palette[MAX_PALETTE]
Definition palette.c:35