Krita Source Code Documentation
Loading...
Searching...
No Matches
KisHistogramPainter::Private Class Reference

Public Member Functions

QImage paintChannels (const QSize &imageSize, const QVector< int > &channels={}, bool logarithmic=false)
 

Static Public Member Functions

static qreal bestCutOffHeight (QPolygonF polygon)
 
static QPair< QColor, QPainter::CompositionMode > computeChannelPaintingInfo (const KoColorSpace *colorSpace, int channel)
 
static QPair< QPolygonF, QPolygonF > computeHistogramShape (KisHistogram *histogram, int channel, quint32 highest)
 
static qreal orientationDeviation (const QPointF &A, const QPointF &B, const QPointF &C)
 
static void paintHistogramShape (QImage &image, const QPolygonF &polygon, qreal scale, const QColor &color, QPainter::CompositionMode compositionMode)
 
static void simplifyHistogramShape (QPolygonF &polygon)
 
static void smoothHistogramShape (QPolygonF &polygon)
 

Public Attributes

QVector< int > channelsToPaint
 
QColor defaultColor
 
QHash< int, HistogramShapeInfohistogramChannelShapeInfo
 
bool isLogarithmic {false}
 
qreal scale {1.0}
 

Static Public Attributes

static constexpr qreal histogramHeightFactor = 0.9
 
static constexpr qreal maximumNeighborWeight = 0.33
 
static constexpr int maximumNumberOfSimplifiedPoints = 3
 
static constexpr qreal maximumOrientationDeviation = M_PI / 16.0
 
static constexpr qreal percentageForPercentile = 0.98
 

Detailed Description

Definition at line 35 of file KisHistogramPainter.cpp.

Member Function Documentation

◆ bestCutOffHeight()

qreal KisHistogramPainter::Private::bestCutOffHeight ( QPolygonF polygon)
static

Definition at line 115 of file KisHistogramPainter.cpp.

116{
117 const int binOfPercentile = static_cast<int>(std::round((1.0 - percentageForPercentile) * (polygon.size() - 4 - 1)));
118 std::nth_element(polygon.begin() + 2,
119 polygon.begin() + 2 + binOfPercentile,
120 polygon.end() - 2,
121 [](const QPointF &p1, const QPointF &p2) ->bool
122 {
123 return p1.y() > p2.y();
124 });
125 const qreal percentile = polygon[binOfPercentile + 2].y();
126 return qFuzzyIsNull(percentile) ? 1.0 : percentile;
127}
QPointF p2
QPointF p1
static constexpr qreal percentageForPercentile
static bool qFuzzyIsNull(half h)

References p1, p2, and qFuzzyIsNull().

◆ computeChannelPaintingInfo()

QPair< QColor, QPainter::CompositionMode > KisHistogramPainter::Private::computeChannelPaintingInfo ( const KoColorSpace * colorSpace,
int channel )
static

Definition at line 171 of file KisHistogramPainter.cpp.

173{
174 Q_ASSERT(colorSpace);
175 Q_ASSERT(channel >= 0);
176
177 QColor color;
178 QPainter::CompositionMode compositionMode = QPainter::CompositionMode_SourceOver;
179
180 if (colorSpace->colorModelId() == RGBAColorModelID) {
181 if (channel == 0) {
182 color = Qt::blue;
183 } else if (channel == 1) {
184 color = Qt::green;
185 } else if (channel == 2) {
186 color = Qt::red;
187 }
188 compositionMode = QPainter::CompositionMode_Plus;
189 } else if (colorSpace->colorModelId() == XYZAColorModelID) {
190 if (channel == 0) {
191 color = Qt::red;
192 } else if (channel == 1) {
193 color = Qt::green;
194 } else if (channel == 2) {
195 color = Qt::blue;
196 }
197 compositionMode = QPainter::CompositionMode_Plus;
198 } else if (colorSpace->colorModelId() == CMYKAColorModelID) {
199 if (channel == 0) {
200 color = Qt::cyan;
201 } else if (channel == 1) {
202 color = Qt::magenta;
203 } else if (channel == 2) {
204 color = Qt::yellow;
205 } else if (channel == 3) {
206 color = Qt::black;
207 }
208 if (channel != 4) {
209 color = KoColor(color, KoColorSpaceRegistry::instance()->rgb8())
210 .convertedTo(colorSpace,
213 .toQColor();
214 compositionMode = QPainter::CompositionMode_Multiply;
215 }
216 }
217
218 return {color, compositionMode};
219}
const KoID XYZAColorModelID("XYZA", ki18n("XYZ/Alpha"))
const KoID CMYKAColorModelID("CMYKA", ki18n("CMYK/Alpha"))
const KoID RGBAColorModelID("RGBA", ki18n("RGB/Alpha"))
virtual KoID colorModelId() const =0
KoColor convertedTo(const KoColorSpace *cs, KoColorConversionTransformation::Intent renderingIntent, KoColorConversionTransformation::ConversionFlags conversionFlags) const
Definition KoColor.cpp:163
void toQColor(QColor *c) const
a convenience method for the above.
Definition KoColor.cpp:198
static KoColorSpaceRegistry * instance()

References CMYKAColorModelID, KoColorSpace::colorModelId(), KoColor::convertedTo(), KoColorConversionTransformation::Empty, KoColorSpaceRegistry::instance(), KoColorConversionTransformation::IntentSaturation, RGBAColorModelID, KoColor::toQColor(), and XYZAColorModelID.

◆ computeHistogramShape()

QPair< QPolygonF, QPolygonF > KisHistogramPainter::Private::computeHistogramShape ( KisHistogram * histogram,
int channel,
quint32 highest )
static

Definition at line 79 of file KisHistogramPainter.cpp.

82{
83 Q_ASSERT(histogram);
84 Q_ASSERT(channel >= 0);
85
86 QPolygonF linearHistogramShape, logarithmicHistogramShape;
87 const int bins = histogram->producer()->numberOfBins();
88 const qreal heightfactor = 1.0 / static_cast<qreal>(highest);
89 const qreal logHeightFactor = 1.0 / std::log(static_cast<qreal>(highest + 1));
90 const qreal widthFactor = 1.0 / static_cast<qreal>(bins);
91
92 // Add extra points at the beginning and end so that the shape is a bit
93 // hidden on the bottom (hides the pen line on the bottom when painting)
94 linearHistogramShape.append(QPointF(0.0, -0.1));
95 linearHistogramShape.append(QPointF(0.0, 0.0));
96 logarithmicHistogramShape.append(QPointF(0.0, -0.1));
97 logarithmicHistogramShape.append(QPointF(0.0, 0.0));
98
99 for (int i = 0; i < bins; ++i) {
100 const QPointF p = QPointF((static_cast<qreal>(i) + 0.5) * widthFactor,
101 static_cast<qreal>(histogram->getValue(i)) * heightfactor);
102 const QPointF logP = QPointF(p.x(), std::log(static_cast<qreal>(histogram->getValue(i) + 1)) * logHeightFactor);
103 linearHistogramShape.append(p);
104 logarithmicHistogramShape.append(logP);
105 }
106
107 linearHistogramShape.append(QPointF(1.0, 0.0));
108 linearHistogramShape.append(QPointF(1.0, -0.1));
109 logarithmicHistogramShape.append(QPointF(1.0, 0.0));
110 logarithmicHistogramShape.append(QPointF(1.0, -0.1));
111
112 return {linearHistogramShape, logarithmicHistogramShape};
113}
const Params2D p
quint32 getValue(quint8 i)
KoHistogramProducer * producer()
virtual qint32 numberOfBins()=0

References KisHistogram::getValue(), KoHistogramProducer::numberOfBins(), p, and KisHistogram::producer().

◆ orientationDeviation()

qreal KisHistogramPainter::Private::orientationDeviation ( const QPointF & A,
const QPointF & B,
const QPointF & C )
static

Definition at line 68 of file KisHistogramPainter.cpp.

71{
72 const QPointF AB = B - A;
73 const QPointF BC = C - B;
74 const qreal angle =KisAlgebra2D::angleBetweenVectors(AB, BC);
75 return angle < -M_PI ? angle + 2.0 * M_PI : (angle > M_PI ? angle - 2.0 * M_PI : angle);
76}
#define C(i, j)
#define M_PI
Definition kis_global.h:111
qreal angleBetweenVectors(const QPointF &v1, const QPointF &v2)

References A, KisAlgebra2D::angleBetweenVectors(), B, C, and M_PI.

◆ paintChannels()

QImage KisHistogramPainter::Private::paintChannels ( const QSize & imageSize,
const QVector< int > & channels = {},
bool logarithmic = false )

Definition at line 244 of file KisHistogramPainter.cpp.

247{
248 QImage image(imageSize, QImage::Format_ARGB32);
249 image.fill(0);
250
251 const int nChannels = histogramChannelShapeInfo.size();
252
253 if (nChannels == 0 || channels.size() == 0) {
254 return image;
255 }
256
257 qreal overallHighest = 0.0;
258 for (int channel : channels) {
259 if (!histogramChannelShapeInfo.contains(channel)) {
260 continue;
261 }
262
263 const qreal channelHighest = static_cast<qreal>(histogramChannelShapeInfo[channel].highest);
264 if (channelHighest > overallHighest) {
265 overallHighest = channelHighest;
266 }
267 }
268
269 for (int channel : channels) {
270 if (!histogramChannelShapeInfo.contains(channel)) {
271 continue;
272 }
273
274 const HistogramShapeInfo &info = histogramChannelShapeInfo[channel];
276 image,
277 logarithmic ? info.logarithmicHistogram : info.linearHistogram,
278 logarithmic
279 ? scale * std::log(info.highest + 1.0) / std::log(overallHighest + 1.0)
280 : scale * info.highest / overallHighest,
281 info.color.isValid() ? info.color : defaultColor,
282 info.compositionMode
283 );
284 }
285
286 return image;
287}
QHash< int, HistogramShapeInfo > histogramChannelShapeInfo
static void paintHistogramShape(QImage &image, const QPolygonF &polygon, qreal scale, const QColor &color, QPainter::CompositionMode compositionMode)
const QVector< int > & channels() const
Get the list of channels that are currently activated (the only ones that will be painted)

References KisHistogramPainter::channels(), HistogramShapeInfo::color, HistogramShapeInfo::compositionMode, KisHistogramPainter::defaultColor(), HistogramShapeInfo::highest, HistogramShapeInfo::linearHistogram, HistogramShapeInfo::logarithmicHistogram, paintHistogramShape(), and KisHistogramPainter::scale().

◆ paintHistogramShape()

void KisHistogramPainter::Private::paintHistogramShape ( QImage & image,
const QPolygonF & polygon,
qreal scale,
const QColor & color,
QPainter::CompositionMode compositionMode )
static

Definition at line 221 of file KisHistogramPainter.cpp.

226{
227 const qreal w = static_cast<qreal>(image.width());
228 const qreal h = static_cast<qreal>(image.height());
229 const qreal maxH = h * histogramHeightFactor;
230
231 QPainter p(&image);
232 p.setRenderHint(QPainter::Antialiasing);
233 p.translate(0.0, h);
234 p.scale(w, -scale * maxH);
235 QPen pen(color, 2);
236 pen.setCosmetic(true);
237 QBrush brush(QColor(color.red(), color.green(), color.blue(), 200));
238 p.setPen(pen);
239 p.setBrush(brush);
240 p.setCompositionMode(compositionMode);
241 p.drawPolygon(polygon);
242}
static constexpr qreal histogramHeightFactor

References p, and KisHistogramPainter::scale().

◆ simplifyHistogramShape()

void KisHistogramPainter::Private::simplifyHistogramShape ( QPolygonF & polygon)
static

Definition at line 148 of file KisHistogramPainter.cpp.

149{
150 if (polygon.size() < 5) {
151 return;
152 }
153
154 qreal accumulatedOrientationDeviation = 0.0;
155 int numberOfSimplifiedPoints = 0;
156
157 for (int i = polygon.size() - 3; i > 1; --i) {
158 accumulatedOrientationDeviation += orientationDeviation(polygon[i + 1], polygon[i], polygon[i - 1]);
159 ++numberOfSimplifiedPoints;
160 if (std::abs(accumulatedOrientationDeviation) > maximumOrientationDeviation ||
161 numberOfSimplifiedPoints > maximumNumberOfSimplifiedPoints) {
162 accumulatedOrientationDeviation = 0.0;
163 numberOfSimplifiedPoints = 0;
164 } else {
165 polygon.remove(i);
166 }
167 }
168}
static constexpr qreal maximumOrientationDeviation
static qreal orientationDeviation(const QPointF &A, const QPointF &B, const QPointF &C)
static constexpr int maximumNumberOfSimplifiedPoints

◆ smoothHistogramShape()

void KisHistogramPainter::Private::smoothHistogramShape ( QPolygonF & polygon)
static

Definition at line 129 of file KisHistogramPainter.cpp.

130{
131 if (polygon.size() < 5) {
132 return;
133 }
134
135 for (int i = 2; i < polygon.size() - 2; ++i) {
136 const qreal leftValue = polygon[i - 1].y();
137 const qreal centerValue = polygon[i].y();
138 const qreal rightValue = polygon[i + 1].y();
139 const qreal leftDelta = std::abs(centerValue - leftValue);
140 const qreal rightDelta = std::abs(centerValue - rightValue);
141 const qreal leftWeight = maximumNeighborWeight * std::exp(-pow2(10.0 * leftDelta));
142 const qreal rightWeight = maximumNeighborWeight * std::exp(-pow2(10.0 * rightDelta));
143 const qreal centerWeight = 1.0 - leftWeight - rightWeight;
144 polygon[i].setY(leftValue * leftWeight + centerValue * centerWeight + rightValue * rightWeight);
145 }
146}
static constexpr qreal maximumNeighborWeight
T pow2(const T &x)
Definition kis_global.h:166

References pow2().

Member Data Documentation

◆ channelsToPaint

QVector<int> KisHistogramPainter::Private::channelsToPaint

Definition at line 45 of file KisHistogramPainter.cpp.

◆ defaultColor

QColor KisHistogramPainter::Private::defaultColor

Definition at line 46 of file KisHistogramPainter.cpp.

◆ histogramChannelShapeInfo

QHash<int, HistogramShapeInfo> KisHistogramPainter::Private::histogramChannelShapeInfo

Definition at line 44 of file KisHistogramPainter.cpp.

◆ histogramHeightFactor

constexpr qreal KisHistogramPainter::Private::histogramHeightFactor = 0.9
staticconstexpr

Definition at line 40 of file KisHistogramPainter.cpp.

◆ isLogarithmic

bool KisHistogramPainter::Private::isLogarithmic {false}

Definition at line 48 of file KisHistogramPainter.cpp.

48{false};

◆ maximumNeighborWeight

constexpr qreal KisHistogramPainter::Private::maximumNeighborWeight = 0.33
staticconstexpr

Definition at line 41 of file KisHistogramPainter.cpp.

◆ maximumNumberOfSimplifiedPoints

constexpr int KisHistogramPainter::Private::maximumNumberOfSimplifiedPoints = 3
staticconstexpr

Definition at line 39 of file KisHistogramPainter.cpp.

◆ maximumOrientationDeviation

constexpr qreal KisHistogramPainter::Private::maximumOrientationDeviation = M_PI / 16.0
staticconstexpr

Definition at line 38 of file KisHistogramPainter.cpp.

◆ percentageForPercentile

constexpr qreal KisHistogramPainter::Private::percentageForPercentile = 0.98
staticconstexpr

Definition at line 42 of file KisHistogramPainter.cpp.

◆ scale

qreal KisHistogramPainter::Private::scale {1.0}

Definition at line 47 of file KisHistogramPainter.cpp.

47{1.0};

The documentation for this class was generated from the following file: