kis_brightness_contrast_filter.cpp 9.06 KB
Newer Older
Boudewijn Rempt's avatar
Boudewijn Rempt committed
1 2 3 4
/*
 * This file is part of Krita
 *
 * Copyright (c) 2004 Cyrille Berger <cberger@cberger.net>
C. Boemann's avatar
C. Boemann committed
5
  * Copyright (c) 2005 C. Boemann <cbo@boemann.dk>
6
*
7 8 9 10
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
Boudewijn Rempt's avatar
Boudewijn Rempt committed
11
 *
12 13 14 15
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
Boudewijn Rempt's avatar
Boudewijn Rempt committed
16
 *
17 18
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
19
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
Boudewijn Rempt's avatar
Boudewijn Rempt committed
20
 */
21

Boudewijn Rempt's avatar
Boudewijn Rempt committed
22 23
#include "kis_brightness_contrast_filter.h"

24 25
#include <math.h>

Sven Langkamp's avatar
Sven Langkamp committed
26
#include <klocale.h>
27

28
#include <QLayout>
29 30
#include <QPixmap>
#include <QPainter>
31
#include <QLabel>
32
#include <QDomDocument>
33
#include <QString>
34
#include <QStringList>
35
#include <QPushButton>
Adrian Page's avatar
Adrian Page committed
36
#include <QHBoxLayout>
37
#include <QColor>
38

39 40
#include "KoBasicHistogramProducers.h"
#include "KoColorSpace.h"
41 42
#include "KoColorTransformation.h"
#include "KoCompositeOp.h"
43

44
#include "kis_config_widget.h"
Boudewijn Rempt's avatar
Boudewijn Rempt committed
45

46
#include "kis_bookmarked_configuration_manager.h"
47
#include "kis_paint_device.h"
48
#include "widgets/kis_curve_widget.h"
49
#include "kis_histogram.h"
50
#include "kis_painter.h"
51 52 53
#include <kis_view2.h>
#include <KoColor.h>
#include <kis_canvas_resource_provider.h>
54

55
KisBrightnessContrastFilterConfiguration::KisBrightnessContrastFilterConfiguration()
Boudewijn Rempt's avatar
Boudewijn Rempt committed
56
        : KisFilterConfiguration("brightnesscontrast", 1)
57 58
{
}
59

60 61 62
KisBrightnessContrastFilterConfiguration::~KisBrightnessContrastFilterConfiguration()
{
}
63

64
void KisBrightnessContrastFilterConfiguration::fromLegacyXML(const QDomElement& root)
65
{
66 67 68
    fromXML(root);
}

69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
void KisBrightnessContrastFilterConfiguration::updateTransfer()
{
    m_transfer = m_curve.uint16Transfer();
}

void KisBrightnessContrastFilterConfiguration::setCurve(const KisCubicCurve &curve)
{
    m_curve = curve;
    updateTransfer();
}

const QVector<quint16>& KisBrightnessContrastFilterConfiguration::transfer() const
{
    return m_transfer;
}

const KisCubicCurve& KisBrightnessContrastFilterConfiguration::curve() const
{
    return m_curve;
}

90 91
void KisBrightnessContrastFilterConfiguration::fromXML(const QDomElement& root)
{
92
    KisCubicCurve curve;
93 94 95 96 97 98
    int version;
    version  = root.attribute("version").toInt();

    QDomElement e = root.firstChild().toElement();
    QString attributeName;

Boudewijn Rempt's avatar
Boudewijn Rempt committed
99
    while (!e.isNull()) {
100
        if ((attributeName = e.attribute("name")) != "nTransfers") {
101 102 103
            QRegExp rx("curve(\\d+)");
            if (rx.indexIn(attributeName, 0) != -1) {
                quint16 index = rx.cap(1).toUShort();
Boudewijn Rempt's avatar
Boudewijn Rempt committed
104 105

                if (index == 0 && !e.text().isEmpty()) {
106 107 108
                    /**
                     * We are going to use first curve only
                     */
109
                    curve.fromString(e.text());
110 111 112
                }
            }
        }
Boudewijn Rempt's avatar
Boudewijn Rempt committed
113 114
        e = e.nextSiblingElement();
    }
115

Boudewijn Rempt's avatar
Boudewijn Rempt committed
116 117
    setVersion(version);
    setCurve(curve);
118 119
}

120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
/**
 * Inherited from KisPropertiesConfiguration
 */
//void KisPerChannelFilterConfiguration::fromXML(const QString& s)

void KisBrightnessContrastFilterConfiguration::toXML(QDomDocument& doc, QDomElement& root) const
{
    /**
     * <params version=1>
     *       <param name="nTransfers">1</param>
     *       <param name="curve0">0,0;0.5,0.5;1,1;</param>
     * </params>
     */

    /* This is a constant for Brightness/Contranst filter */
    const qint32 numTransfers = 1;
Boudewijn Rempt's avatar
Boudewijn Rempt committed
136

137 138

    root.setAttribute("version", version());
Boudewijn Rempt's avatar
Boudewijn Rempt committed
139

140 141 142 143 144 145 146 147
    QDomElement t = doc.createElement("param");
    QDomText text = doc.createTextNode(QString::number(numTransfers));
    t.setAttribute("name", "nTransfers");
    t.appendChild(text);
    root.appendChild(t);

    t = doc.createElement("param");
    t.setAttribute("name", "curve0");
148

149
    text = doc.createTextNode(m_curve.toString());
150 151
    t.appendChild(text);
    root.appendChild(t);
152 153
}

154 155 156 157 158 159
/**
 * Inherited from KisPropertiesConfiguration
 */
//QString KisPerChannelFilterConfiguration::toXML()


160
KisBrightnessContrastFilter::KisBrightnessContrastFilter()
161
        : KisColorTransformationFilter(id(), categoryAdjust(), i18n("&Brightness/Contrast curve..."))
162
{
163
    setSupportsPainting(false);
164
    setColorSpaceIndependence(TO_LAB16);
165 166
}

167
KisConfigWidget * KisBrightnessContrastFilter::createConfigurationWidget(QWidget *parent, const KisPaintDeviceSP dev) const
168
{
169
    return new KisBrightnessContrastConfigWidget(parent, dev);
170 171
}

172
KisFilterConfiguration* KisBrightnessContrastFilter::factoryConfiguration(const KisPaintDeviceSP)
Boudewijn Rempt's avatar
Boudewijn Rempt committed
173
const
174
{
175
    return new KisBrightnessContrastFilterConfiguration();
176 177
}

178
KoColorTransformation* KisBrightnessContrastFilter::createTransformation(const KoColorSpace* cs, const KisFilterConfiguration* config) const
179
{
Boudewijn Rempt's avatar
Boudewijn Rempt committed
180 181
    const KisBrightnessContrastFilterConfiguration* configBC = dynamic_cast<const KisBrightnessContrastFilterConfiguration*>(config);
    if (!configBC) return 0;
182

183
    KoColorTransformation * adjustment = cs->createBrightnessContrastAdjustment(configBC->transfer().constData());
184
    return adjustment;
185
}
186

187
KisBrightnessContrastConfigWidget::KisBrightnessContrastConfigWidget(QWidget * parent, KisPaintDeviceSP dev, Qt::WFlags f)
188
        : KisConfigWidget(parent, f)
189
{
Casper Boemann's avatar
Casper Boemann committed
190 191
    int i;
    int height;
192
    m_page = new WdgBrightnessContrast(this);
Adrian Page's avatar
Adrian Page committed
193
    QHBoxLayout * l = new QHBoxLayout(this);
194
    Q_CHECK_PTR(l);
195

196 197 198 199 200 201 202 203
    //Hide these buttons and labels as they are not implemented in 1.5
    m_page->pb_more_contrast->hide();
    m_page->pb_less_contrast->hide();
    m_page->pb_more_brightness->hide();
    m_page->pb_less_brightness->hide();
    m_page->textLabelBrightness->hide();
    m_page->textLabelContrast->hide();

204 205 206
    l->addWidget(m_page, 1, Qt::AlignTop);
    l->setContentsMargins(0,0,0,0);
    
Casper Boemann's avatar
Casper Boemann committed
207
    height = 256;
208
    connect(m_page->curveWidget, SIGNAL(modified()), SIGNAL(sigConfigurationItemChanged()));
Casper Boemann's avatar
Casper Boemann committed
209 210 211 212

    // Create the horizontal gradient label
    QPixmap hgradientpix(256, 1);
    QPainter hgp(&hgradientpix);
Bernhard Rosenkraenzer's avatar
Bernhard Rosenkraenzer committed
213
    hgp.setPen(QPen(QColor(0, 0, 0), 1, Qt::SolidLine));
Boudewijn Rempt's avatar
Boudewijn Rempt committed
214 215
    for (i = 0; i < 256; ++i) {
        hgp.setPen(QColor(i, i, i));
Casper Boemann's avatar
Casper Boemann committed
216 217 218
        hgp.drawPoint(i, 0);
    }
    m_page->hgradient->setPixmap(hgradientpix);
219

Casper Boemann's avatar
Casper Boemann committed
220 221 222
    // Create the vertical gradient label
    QPixmap vgradientpix(1, 256);
    QPainter vgp(&vgradientpix);
Bernhard Rosenkraenzer's avatar
Bernhard Rosenkraenzer committed
223
    vgp.setPen(QPen(QColor(0, 0, 0), 1, Qt::SolidLine));
Boudewijn Rempt's avatar
Boudewijn Rempt committed
224 225 226
    for (i = 0; i < 256; ++i) {
        vgp.setPen(QColor(i, i, i));
        vgp.drawPoint(0, 255 - i);
Casper Boemann's avatar
Casper Boemann committed
227 228
    }
    m_page->vgradient->setPixmap(vgradientpix);
229

230
    KoHistogramProducerSP producer = KoHistogramProducerSP(new KoGenericLabHistogramProducer());
231
    KisHistogram histogram(dev, dev->exactBounds(), producer, LINEAR);
Casper Boemann's avatar
Casper Boemann committed
232 233 234
    QPixmap pix(256, height);
    pix.fill();
    QPainter p(&pix);
Bernhard Rosenkraenzer's avatar
Bernhard Rosenkraenzer committed
235
    p.setPen(QPen(Qt::gray, 1, Qt::SolidLine));
236 237

    double highest = (double)histogram.calculations().getHighest();
Laurent Montel's avatar
Laurent Montel committed
238
    qint32 bins = histogram.producer()->numberOfBins();
239 240 241

    if (histogram.getHistogramType() == LINEAR) {
        double factor = (double)height / highest;
Boudewijn Rempt's avatar
Boudewijn Rempt committed
242
        for (i = 0; i < bins; ++i) {
243
            p.drawLine(i, height, i, height - int(histogram.getValue(i) * factor));
Casper Boemann's avatar
Casper Boemann committed
244 245
        }
    } else {
246
        double factor = (double)height / (double)log(highest);
Boudewijn Rempt's avatar
Boudewijn Rempt committed
247
        for (i = 0; i < bins; ++i) {
248
            p.drawLine(i, height, i, height - int(log((double)histogram.getValue(i)) * factor));
Casper Boemann's avatar
Casper Boemann committed
249 250
        }
    }
251

252
    m_page->curveWidget->setPixmap(pix);
253 254
    m_page->curveWidget->setBasePixmap(pix);
}
Casper Boemann's avatar
Casper Boemann committed
255

256 257 258 259
KisBrightnessContrastConfigWidget::~KisBrightnessContrastConfigWidget()
{
    KoToolManager::instance()->switchBackRequested();
    delete m_page;
260 261
}

Cyrille Berger's avatar
Cyrille Berger committed
262
KisBrightnessContrastFilterConfiguration * KisBrightnessContrastConfigWidget::configuration() const
263
{
264
    KisBrightnessContrastFilterConfiguration * cfg = new KisBrightnessContrastFilterConfiguration();
265
    cfg->setCurve(m_page->curveWidget->curve());
266
    return cfg;
267
}
268

269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288
void KisBrightnessContrastConfigWidget::slotDrawLine(const KoColor &color)
{
    QColor colorNew = color.toQColor();
    int i = (colorNew.red() + colorNew.green() + colorNew.blue())/3 ;
    QPixmap pix = m_page->curveWidget->getBasePixmap();
    QPainter p(&pix);
    p.setPen(QPen(Qt::black, 1, Qt::SolidLine));
    p.drawLine(i,0,i,255);
    QString label = "x:";
    label.insert(2,QString(QString::number(i)));
    p.drawText(i,250,label);
    m_page->curveWidget->setPixmap(pix);
}

void KisBrightnessContrastConfigWidget::setView(KisView2 *view)
{
    connect(view->resourceProvider(), SIGNAL(sigFGColorChanged(const KoColor&)), this, SLOT(slotDrawLine(const KoColor&)));
    KoToolManager::instance()->switchToolTemporaryRequested("KritaSelected/KisToolColorPicker");
}

289
void KisBrightnessContrastConfigWidget::setConfiguration(const KisPropertiesConfiguration * config)
290
{
291
    const KisBrightnessContrastFilterConfiguration * cfg = dynamic_cast<const KisBrightnessContrastFilterConfiguration *>(config);
292
    Q_ASSERT(cfg);
293
    m_page->curveWidget->setCurve(cfg->curve());
294
}
Adrian Page's avatar
Adrian Page committed
295

296

Adrian Page's avatar
Adrian Page committed
297 298
#include "kis_brightness_contrast_filter.moc"