Krita Source Code Documentation
Loading...
Searching...
No Matches
KisColorfulBrush.cpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2020 Dmitry Kazakov <dimula73@gmail.com>
3 *
4 * SPDX-License-Identifier: GPL-2.0-or-later
5 */
6
7#include "KisColorfulBrush.h"
8
9
10KisColorfulBrush::KisColorfulBrush(const QString &filename)
11 : KisScalingSizeBrush(filename)
12{
13}
14
15#include <KoColorSpaceMaths.h>
16#include <KoColorSpaceTraits.h>
17
18namespace {
19
20qreal estimateImageAverage(const QImage &image) {
21 qint64 lightnessSum = 0;
22 qint64 alphaSum = 0;
23
24 KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(image.format() == QImage::Format_ARGB32, 0.5);
25
26 for (int y = 0; y < image.height(); ++y) {
27 const QRgb *pixel = reinterpret_cast<const QRgb*>(image.scanLine(y));
28
29 for (int i = 0; i < image.width(); ++i) {
30 lightnessSum += qRound(qGray(*pixel) * qAlpha(*pixel) / 255.0);
31 alphaSum += qAlpha(*pixel);
32 pixel++;
33 }
34 }
35
36 if (alphaSum == 0) {
37 return 0;
38 }
39 return 255.0 * qreal(lightnessSum) / alphaSum;
40}
41
42}
43
45{
46 return estimateImageAverage(KisBrush::brushTipImage());
47}
48
50{
51 return estimateImageAverage(this->brushTipImage());
52}
53
58
63
65{
68
69 KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(image.format() == QImage::Format_ARGB32, image);
70
71 const qreal adjustmentMidPoint =
73 estimateImageAverage(image) :
75
76 if (qAbs(adjustmentMidPoint - 127.0) > 0.1 ||
79
82
83 const qreal midX = adjustmentMidPoint;
84 const qreal midY = m_brightnessAdjustment > 0 ?
87
88 qreal loA = 0.0;
89 qreal hiA = 0.0;
90
91 qreal loB = 0.0;
92 qreal hiB = 255.0;
93
95 if (m_contrastAdjustment > 0.0) {
96 loA = midY / (1.0 - m_contrastAdjustment) / midX;
97 hiA = (unit - midY) / (1.0 - m_contrastAdjustment) / (unit - midX);
98 } else {
99 loA = midY * (1.0 + m_contrastAdjustment) / midX;
100 hiA = (unit - midY) * (1.0 + m_contrastAdjustment) / (unit - midX);
101 }
102
103 loB = midY - midX * loA;
104 hiB = midY - midX * hiA;
105 }
106
107 for (int y = 0; y < image.height(); y++) {
108 QRgb *pixel = reinterpret_cast<QRgb *>(image.scanLine(y));
109 for (int x = 0; x < image.width(); x++) {
110 QRgb c = pixel[x];
111
112 int v = qGray(c);
113
114 if (v >= midX) {
115 v = qMin(unit, qRound(hiA * v + hiB));
116 } else {
117 v = qMax(0, qRound(loA * v + loB));
118 }
119
120 pixel[x] = qRgba(v, v, v, qAlpha(c));
121 }
122 }
123 } else {
124 for (int y = 0; y < image.height(); y++) {
125 QRgb *pixel = reinterpret_cast<QRgb *>(image.scanLine(y));
126 for (int x = 0; x < image.width(); x++) {
127 QRgb c = pixel[x];
128
129 int v = qGray(c);
130 pixel[x] = qRgba(v, v, v, qAlpha(c));
131 }
132 }
133 }
134 }
135 return image;
136}
137
145
153
161
163{
164 return brushType() == IMAGE || brushType() == PIPE_IMAGE;
165}
166
171
176
181
182#include <QDomElement>
183
184void KisColorfulBrush::toXML(QDomDocument& d, QDomElement& e) const
185{
186 // legacy setting, now 'brushApplication' is used instead
187 e.setAttribute("ColorAsMask", QString::number((int)(brushApplication() != IMAGESTAMP)));
188
189 e.setAttribute("AdjustmentMidPoint", QString::number(m_adjustmentMidPoint));
190 e.setAttribute("BrightnessAdjustment", QString::number(m_brightnessAdjustment));
191 e.setAttribute("ContrastAdjustment", QString::number(m_contrastAdjustment));
192 e.setAttribute("AutoAdjustMidPoint", QString::number(m_autoAdjustMidPoint));
193 e.setAttribute("AdjustmentVersion", QString::number(2));
194 KisBrush::toXML(d, e);
195}
196
201
float value(const T *src, size_t ch)
qreal v
virtual enumBrushApplication brushApplication() const
virtual enumBrushType brushType() const
virtual QImage brushTipImage() const
brushImage the image the brush tip can paint with. Not all brush types have a single image.
Private *const d
Definition kis_brush.h:387
virtual void toXML(QDomDocument &, QDomElement &) const
void clearBrushPyramid()
bool autoAdjustMidPoint() const
KisColorfulBrush()=default
virtual void setAdjustmentMidPoint(quint8 value)
virtual bool isImageType() const
QImage brushTipImage() const override
brushImage the image the brush tip can paint with. Not all brush types have a single image.
bool hasColorAndTransparency() const
qreal contrastAdjustment() const
virtual void setContrastAdjustment(qreal value)
qreal brightnessAdjustment() const
quint8 adjustmentMidPoint() const
qreal adjustedMidPoint() const
virtual void setBrightnessAdjustment(qreal value)
virtual void setAutoAdjustMidPoint(bool autoAdjustMidPoint)
void setHasColorAndTransparency(bool value)
void toXML(QDomDocument &d, QDomElement &e) const override
qreal estimatedSourceMidPoint() const
static _T blend(_T a, _T b, _T alpha)
static bool qFuzzyCompare(half p1, half p2)
static bool qFuzzyIsNull(half h)
#define KIS_SAFE_ASSERT_RECOVER_RETURN_VALUE(cond, val)
Definition kis_assert.h:129
@ IMAGE
Definition kis_brush.h:33
@ PIPE_IMAGE
Definition kis_brush.h:35
@ IMAGESTAMP
Definition kis_brush.h:40
unsigned int QRgb
QImage image