• Skip to content
  • Skip to link menu
KDE 4.4 API Reference
  • KDE API Reference
  • API Reference
  • Sitemap
  • Contact Us
 

digikam

adjustlevelstool.cpp

Go to the documentation of this file.
00001 /* ============================================================
00002  *
00003  * This file is a part of digiKam project
00004  * http://www.digikam.org
00005  *
00006  * Date        : 2004-07-20
00007  * Description : image histogram adjust levels.
00008  *
00009  * Copyright (C) 2004-2009 by Gilles Caulier <caulier dot gilles at gmail dot com>
00010  *
00011  * This program is free software; you can redistribute it
00012  * and/or modify it under the terms of the GNU General
00013  * Public License as published by the Free Software Foundation;
00014  * either version 2, or (at your option)
00015  * any later version.
00016  *
00017  * This program is distributed in the hope that it will be useful,
00018  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00019  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00020  * GNU General Public License for more details.
00021  *
00022  * ============================================================ */
00023 
00024 #include "adjustlevelstool.moc"
00025 
00026 // C++ includes
00027 
00028 #include <cmath>
00029 
00030 // Qt includes
00031 
00032 #include <QButtonGroup>
00033 #include <QColor>
00034 #include <QFrame>
00035 #include <QGridLayout>
00036 #include <QGroupBox>
00037 #include <QHBoxLayout>
00038 #include <QLabel>
00039 #include <QPainter>
00040 #include <QPixmap>
00041 #include <QPushButton>
00042 #include <QTimer>
00043 #include <QToolButton>
00044 
00045 // KDE includes
00046 
00047 #include <kaboutdata.h>
00048 #include <kapplication.h>
00049 #include <kconfig.h>
00050 #include <kcursor.h>
00051 #include <kfiledialog.h>
00052 #include <kglobal.h>
00053 #include <kglobalsettings.h>
00054 #include <khelpmenu.h>
00055 #include <kicon.h>
00056 #include <kiconloader.h>
00057 #include <klocale.h>
00058 #include <kmenu.h>
00059 #include <kmessagebox.h>
00060 #include <kstandarddirs.h>
00061 
00062 // LibKDcraw includes
00063 
00064 #include <libkdcraw/rnuminput.h>
00065 
00066 // Local includes
00067 
00068 #include "daboutdata.h"
00069 #include "dgradientslider.h"
00070 #include "dimg.h"
00071 #include "dimgimagefilters.h"
00072 #include "editortoolsettings.h"
00073 #include "histogrambox.h"
00074 #include "histogramwidget.h"
00075 #include "imagehistogram.h"
00076 #include "imageiface.h"
00077 #include "imagelevels.h"
00078 #include "imagewidget.h"
00079 #include "version.h"
00080 
00081 using namespace KDcrawIface;
00082 using namespace Digikam;
00083 
00084 namespace DigikamAdjustLevelsImagesPlugin
00085 {
00086 
00087 class AdjustLevelsToolPriv
00088 {
00089 public:
00090 
00091     AdjustLevelsToolPriv() :
00092         configGroupName("adjustlevels Tool"),
00093         configGammaChannelEntry("GammaChannel%1"),
00094         configLowInputChannelEntry("LowInputChannel%1"),
00095         configLowOutputChannelEntry("LowOutputChannel%1"),
00096         configHighInputChannelEntry("HighInputChannel%1"),
00097         configHighOutputChannelEntry("HighOutputChannel%1"),
00098         configHistogramChannelEntry("Histogram Channel"),
00099         configHistogramScaleEntry("Histogram Scale"),
00100 
00101         destinationPreviewData(0),
00102         histoSegments(0),
00103         currentPreviewMode(0),
00104         pickerBox(0),
00105         resetButton(0),
00106         autoButton(0),
00107         pickBlack(0),
00108         pickGray(0),
00109         pickWhite(0),
00110         pickerColorButtonGroup(0),
00111         minInput(0),
00112         maxInput(0),
00113         minOutput(0),
00114         maxOutput(0),
00115         gammaInput(0),
00116         levelsHistogramWidget(0),
00117         inputLevels(0),
00118         outputLevels(0),
00119         previewWidget(0),
00120         levels(0),
00121         originalImage(0),
00122         gboxSettings(0)
00123         {}
00124 
00125     const QString        configGroupName;
00126     const QString        configGammaChannelEntry;
00127     const QString        configLowInputChannelEntry;
00128     const QString        configLowOutputChannelEntry;
00129     const QString        configHighInputChannelEntry;
00130     const QString        configHighOutputChannelEntry;
00131     const QString        configHistogramChannelEntry;
00132     const QString        configHistogramScaleEntry;
00133 
00134     uchar*               destinationPreviewData;
00135 
00136     int                  histoSegments;
00137     int                  currentPreviewMode;
00138 
00139     QWidget*             pickerBox;
00140 
00141     QPushButton*         resetButton;
00142     QToolButton*         autoButton;
00143     QToolButton*         pickBlack;
00144     QToolButton*         pickGray;
00145     QToolButton*         pickWhite;
00146 
00147     QButtonGroup*        pickerColorButtonGroup;
00148 
00149     RIntNumInput*        minInput;
00150     RIntNumInput*        maxInput;
00151     RIntNumInput*        minOutput;
00152     RIntNumInput*        maxOutput;
00153 
00154     RDoubleNumInput*     gammaInput;
00155 
00156     HistogramWidget*     levelsHistogramWidget;
00157 
00158     DGradientSlider*     inputLevels;
00159     DGradientSlider*     outputLevels;
00160 
00161     ImageWidget*         previewWidget;
00162 
00163     ImageLevels*         levels;
00164 
00165     DImg*                originalImage;
00166 
00167     EditorToolSettings*  gboxSettings;
00168 };
00169 
00170 AdjustLevelsTool::AdjustLevelsTool(QObject* parent)
00171                 : EditorTool(parent),
00172                   d(new AdjustLevelsToolPriv)
00173 {
00174     setObjectName("adjustlevels");
00175     setToolName(i18n("Adjust Levels"));
00176     setToolIcon(SmallIcon("adjustlevels"));
00177 
00178     d->destinationPreviewData = 0;
00179 
00180     ImageIface iface(0, 0);
00181     d->originalImage = iface.getOriginalImg();
00182 
00183     d->histoSegments = d->originalImage->sixteenBit() ? 65535 : 255;
00184     d->levels        = new ImageLevels(d->originalImage->sixteenBit());
00185 
00186     // -------------------------------------------------------------
00187 
00188     d->previewWidget = new ImageWidget("adjustlevels Tool", 0,
00189             i18n("Here you can see the image's "
00190                  "level-adjustments preview. You can pick a spot on the image "
00191                  "to see the corresponding level in the histogram."));
00192 
00193     setToolView(d->previewWidget);
00194 
00195     // -------------------------------------------------------------
00196 
00197     d->gboxSettings = new EditorToolSettings;
00198     d->gboxSettings->setButtons(EditorToolSettings::Default|
00199                                 EditorToolSettings::Load|
00200                                 EditorToolSettings::SaveAs|
00201                                 EditorToolSettings::Ok|
00202                                 EditorToolSettings::Cancel);
00203 
00204     d->gboxSettings->setTools(EditorToolSettings::Histogram);
00205     d->gboxSettings->setHistogramType(Digikam::LRGBA);
00206 
00207     // we don't need to use the Gradient widget in this tool
00208     d->gboxSettings->histogramBox()->setGradientVisible(false);
00209 
00210 
00211     d->levelsHistogramWidget = new HistogramWidget(256, 140, d->originalImage->bits(),
00212                                                              d->originalImage->width(),
00213                                                              d->originalImage->height(),
00214                                                              d->originalImage->sixteenBit(),
00215                                                              d->gboxSettings->plainPage(), false);
00216     d->levelsHistogramWidget->setWhatsThis( i18n("This is the histogram drawing of the selected channel "
00217                                                  "from the original image."));
00218 
00219     // -------------------------------------------------------------
00220 
00221     d->inputLevels = new DGradientSlider();
00222     d->inputLevels->setWhatsThis( i18n("Select the input intensity of the histogram here."));
00223     d->inputLevels->setToolTip( i18n( "Input intensity." ) );
00224     d->inputLevels->installEventFilter(this);
00225 
00226     d->outputLevels = new DGradientSlider();
00227     d->outputLevels->setWhatsThis( i18n("Select the output intensity of the histogram here."));
00228     d->outputLevels->setToolTip( i18n( "Output intensity." ) );
00229     d->outputLevels->installEventFilter(this);
00230 
00231     d->minInput = new RIntNumInput();
00232     d->minInput->setRange(0, d->histoSegments, 1);
00233     d->minInput->setSliderEnabled(false);
00234     d->minInput->setDefaultValue(0);
00235     d->minInput->setWhatsThis( i18n("Select the minimal input intensity value of the histogram here."));
00236     d->minInput->setToolTip( i18n( "Minimal input intensity." ) );
00237 
00238     d->gammaInput = new RDoubleNumInput();
00239     d->gammaInput->setDecimals(2);
00240     d->gammaInput->setRange(0.1, 3.0, 0.01);
00241     d->gammaInput->setDefaultValue(1.0);
00242     d->gammaInput->setToolTip( i18n( "Gamma input value." ) );
00243     d->gammaInput->setWhatsThis( i18n("Select the gamma input value here."));
00244 
00245     d->maxInput = new RIntNumInput();
00246     d->maxInput->setRange(0, d->histoSegments, 1);
00247     d->maxInput->setSliderEnabled(false);
00248     d->maxInput->setDefaultValue(d->histoSegments);
00249     d->maxInput->setToolTip( i18n( "Maximal input intensity." ) );
00250     d->maxInput->setWhatsThis( i18n("Select the maximal input intensity value of the histogram here."));
00251 
00252     d->minOutput = new RIntNumInput();
00253     d->minOutput->setRange(0, d->histoSegments, 1);
00254     d->minOutput->setSliderEnabled(false);
00255     d->minOutput->setDefaultValue(0);
00256     d->minOutput->setToolTip( i18n( "Minimal output intensity." ) );
00257     d->minOutput->setWhatsThis( i18n("Select the minimal output intensity value of the histogram here."));
00258 
00259     d->maxOutput = new RIntNumInput();
00260     d->maxOutput->setRange(0, d->histoSegments, 1);
00261     d->maxOutput->setSliderEnabled(false);
00262     d->maxOutput->setDefaultValue(d->histoSegments);
00263     d->maxOutput->setToolTip( i18n( "Maximal output intensity." ) );
00264     d->maxOutput->setWhatsThis( i18n("Select the maximal output intensity value of the histogram here."));
00265 
00266     // -------------------------------------------------------------
00267 
00268     d->pickerBox = new QWidget();
00269 
00270     d->pickBlack = new QToolButton();
00271     d->pickBlack->setIcon(KIcon("color-picker-black"));
00272     d->pickBlack->setCheckable(true);
00273     d->pickBlack->setToolTip( i18n( "All channels shadow tone color picker" ) );
00274     d->pickBlack->setWhatsThis(i18n("With this button, you can pick the color from the original "
00275                                     "image used to set <b>Shadow Tone</b> "
00276                                     "input levels on the Red, Green, Blue, and Luminosity channels."));
00277 
00278     d->pickGray  = new QToolButton();
00279     d->pickGray->setIcon(KIcon("color-picker-grey"));
00280     d->pickGray->setCheckable(true);
00281     d->pickGray->setToolTip( i18n( "All channels middle tone color picker" ) );
00282     d->pickGray->setWhatsThis(i18n("With this button, you can pick the color from the original "
00283                                    "image used to set <b>Middle Tone</b> "
00284                                    "input levels on the Red, Green, Blue, and Luminosity channels."));
00285 
00286     d->pickWhite = new QToolButton();
00287     d->pickWhite->setIcon(KIcon("color-picker-white"));
00288     d->pickWhite->setCheckable(true);
00289     d->pickWhite->setToolTip( i18n( "All channels highlight tone color picker" ) );
00290     d->pickWhite->setWhatsThis(i18n("With this button, you can pick the color from the original "
00291                                     "image used to set <b>Highlight Tone</b> "
00292                                     "input levels on the Red, Green, Blue, and Luminosity channels."));
00293 
00294     d->pickerColorButtonGroup = new QButtonGroup(d->pickerBox);
00295     d->pickerColorButtonGroup->addButton(d->pickBlack, BlackTonal);
00296     d->pickerColorButtonGroup->addButton(d->pickGray, GrayTonal);
00297     d->pickerColorButtonGroup->addButton(d->pickWhite, WhiteTonal);
00298 
00299     QHBoxLayout *pickerBoxLayout = new QHBoxLayout;
00300     pickerBoxLayout->setMargin(0);
00301     pickerBoxLayout->setSpacing(0);
00302     pickerBoxLayout->addWidget(d->pickBlack);
00303     pickerBoxLayout->addWidget(d->pickGray);
00304     pickerBoxLayout->addWidget(d->pickWhite);
00305     d->pickerBox->setLayout(pickerBoxLayout);
00306 
00307     d->pickerColorButtonGroup->setExclusive(true);
00308 
00309     // -------------------------------------------------------------
00310 
00311     d->autoButton = new QToolButton();
00312     d->autoButton->setIcon(KIconLoader::global()->loadIcon("system-run", KIconLoader::Toolbar));
00313     d->autoButton->setToolTip( i18n( "Adjust all levels automatically." ) );
00314     d->autoButton->setWhatsThis(i18n("If you press this button, all channel levels will be adjusted "
00315                                      "automatically."));
00316 
00317     d->resetButton = new QPushButton(i18n("&Reset"));
00318     d->resetButton->setIcon(KIconLoader::global()->loadIcon("document-revert", KIconLoader::Toolbar));
00319     d->resetButton->setToolTip( i18n( "Reset current channel levels' values." ) );
00320     d->resetButton->setWhatsThis(i18n("If you press this button, all levels' values "
00321                                       "from the currently selected channel "
00322                                       "will be reset to the default values."));
00323 
00324     QLabel *space = new QLabel();
00325     space->setFixedWidth(d->gboxSettings->spacingHint());
00326 
00327     QHBoxLayout* l3 = new QHBoxLayout();
00328     l3->addWidget(d->pickerBox);
00329     l3->addWidget(d->autoButton);
00330     l3->addWidget(space);
00331     l3->addWidget(d->resetButton);
00332     l3->addStretch(10);
00333 
00334     // -------------------------------------------------------------
00335 
00336     QGridLayout* mainLayout = new QGridLayout();
00337     mainLayout->setSpacing(d->gboxSettings->spacingHint());
00338     mainLayout->addWidget(d->levelsHistogramWidget, 0, 1, 1, 5);
00339     mainLayout->addWidget(d->inputLevels,           1, 0, 1, 7);
00340     mainLayout->addWidget(d->minInput,              2, 1, 1, 1);
00341     mainLayout->addWidget(d->maxInput,              2, 5, 1, 1);
00342     mainLayout->addWidget(d->gammaInput,            3, 0, 1, 7);
00343     mainLayout->addWidget(d->outputLevels,          4, 0, 1, 7);
00344     mainLayout->addWidget(d->minOutput,             5, 1, 1, 1);
00345     mainLayout->addWidget(d->maxOutput,             5, 5, 1, 1);
00346     mainLayout->addLayout(l3,                       6, 0, 1, 7);
00347     mainLayout->setRowStretch(7, 10);
00348     mainLayout->setColumnStretch(2, 10);
00349     mainLayout->setColumnStretch(4, 10);
00350     mainLayout->setMargin(0);
00351     mainLayout->setSpacing(d->gboxSettings->spacingHint());
00352     d->gboxSettings->plainPage()->setLayout(mainLayout);
00353 
00354     // -------------------------------------------------------------
00355 
00356     setToolSettings(d->gboxSettings);
00357     init();
00358 
00359     // -------------------------------------------------------------
00360 
00361     // Channels and scale selection slots.
00362 
00363     connect(d->previewWidget, SIGNAL(spotPositionChangedFromOriginal(const Digikam::DColor&, const QPoint&)),
00364             this, SLOT(slotSpotColorChanged(const Digikam::DColor&)));
00365 
00366     connect(d->previewWidget, SIGNAL(spotPositionChangedFromTarget(const Digikam::DColor&, const QPoint&)),
00367             this, SLOT(slotColorSelectedFromTarget(const Digikam::DColor&)));
00368 
00369     connect(d->previewWidget, SIGNAL(signalResized()),
00370             this, SLOT(slotEffect()));
00371 
00372     // -------------------------------------------------------------
00373     // Color sliders and spinbox slots.
00374 
00375     connect(d->inputLevels, SIGNAL(leftValueChanged(double)),
00376             this, SLOT(slotAdjustMinInputSpinBox(double)));
00377 
00378     connect(d->inputLevels, SIGNAL(rightValueChanged(double)),
00379             this, SLOT(slotAdjustMaxInputSpinBox(double)));
00380 
00381     connect(d->outputLevels, SIGNAL(leftValueChanged(double)),
00382             this, SLOT(slotAdjustMinOutputSpinBox(double)));
00383 
00384     connect(d->outputLevels, SIGNAL(rightValueChanged(double)),
00385             this, SLOT(slotAdjustMaxOutputSpinBox(double)));
00386 
00387     connect(d->minInput, SIGNAL(valueChanged(int)),
00388             this, SLOT(slotAdjustSliders()));
00389 
00390     connect(d->maxInput, SIGNAL(valueChanged(int)),
00391             this, SLOT(slotAdjustSliders()));
00392 
00393     connect(d->minOutput, SIGNAL(valueChanged(int)),
00394             this, SLOT(slotAdjustSliders()));
00395 
00396     connect(d->maxOutput, SIGNAL(valueChanged(int)),
00397             this, SLOT(slotAdjustSliders()));
00398 
00399     connect(d->gammaInput, SIGNAL(valueChanged(double)),
00400             this, SLOT(slotGammaInputchanged(double)));
00401 
00402     // -------------------------------------------------------------
00403     // Buttons slots.
00404 
00405     connect(d->autoButton, SIGNAL(clicked()),
00406             this, SLOT(slotAutoLevels()));
00407 
00408     connect(d->resetButton, SIGNAL(clicked()),
00409             this, SLOT(slotResetCurrentChannel()));
00410 
00411     connect(d->pickerColorButtonGroup, SIGNAL(buttonReleased(int)),
00412             this, SLOT(slotPickerColorButtonActived()));
00413 }
00414 
00415 AdjustLevelsTool::~AdjustLevelsTool()
00416 {
00417     delete [] d->destinationPreviewData;
00418     delete d->levels;
00419     delete d;
00420 }
00421 
00422 void AdjustLevelsTool::slotPickerColorButtonActived()
00423 {
00424     // Save previous rendering mode and toggle to original image.
00425     d->currentPreviewMode = d->previewWidget->getRenderingPreviewMode();
00426     d->previewWidget->setRenderingPreviewMode(ImageGuideWidget::PreviewOriginalImage);
00427 }
00428 
00429 void AdjustLevelsTool::slotSpotColorChanged(const DColor& color)
00430 {
00431     if ( d->pickBlack->isChecked() )
00432     {
00433        // Black tonal levels point.
00434        d->levels->levelsBlackToneAdjustByColors(d->gboxSettings->histogramBox()->channel(), color);
00435        d->pickBlack->setChecked(false);
00436     }
00437     else if ( d->pickGray->isChecked() )
00438     {
00439        // Gray tonal levels point.
00440        d->levels->levelsGrayToneAdjustByColors(d->gboxSettings->histogramBox()->channel(), color);
00441        d->pickGray->setChecked(false);
00442     }
00443     else if ( d->pickWhite->isChecked() )
00444     {
00445        // White tonal levels point.
00446        d->levels->levelsWhiteToneAdjustByColors(d->gboxSettings->histogramBox()->channel(), color);
00447        d->pickWhite->setChecked(false);
00448     }
00449     else
00450     {
00451        d->levelsHistogramWidget->setHistogramGuideByColor(color);
00452        return;
00453     }
00454 
00455     // Refresh the current levels config.
00456     slotChannelChanged();
00457 
00458     // restore previous rendering mode.
00459     d->previewWidget->setRenderingPreviewMode(d->currentPreviewMode);
00460 
00461     slotEffect();
00462 }
00463 
00464 void AdjustLevelsTool::slotColorSelectedFromTarget( const DColor& color )
00465 {
00466     d->gboxSettings->histogramBox()->histogram()->setHistogramGuideByColor(color);
00467 }
00468 
00469 void AdjustLevelsTool::slotGammaInputchanged(double val)
00470 {
00471     blockSignals(true);
00472     d->levels->setLevelGammaValue(d->gboxSettings->histogramBox()->channel(), val);
00473     blockSignals(false);
00474     slotTimer();
00475 }
00476 
00477 void AdjustLevelsTool::slotAdjustMinInputSpinBox(double val)
00478 {
00479     d->minInput->blockSignals(true);
00480     int newVal = (int)(val*d->histoSegments);
00481     d->minInput->setValue(newVal);
00482     d->minInput->blockSignals(false);
00483     slotAdjustSliders();
00484 }
00485 
00486 void AdjustLevelsTool::slotAdjustMaxInputSpinBox(double val)
00487 {
00488     d->maxInput->blockSignals(true);
00489     int newVal = (int)(val*d->histoSegments);
00490     d->maxInput->setValue(newVal);
00491     d->maxInput->blockSignals(false);
00492     slotAdjustSliders();
00493 }
00494 
00495 void AdjustLevelsTool::slotAdjustMinOutputSpinBox(double val)
00496 {
00497     d->minOutput->blockSignals(true);
00498     int newVal = (int)(val*d->histoSegments);
00499     d->minOutput->setValue(newVal);
00500     d->minOutput->blockSignals(false);
00501     slotAdjustSliders();
00502 }
00503 
00504 void AdjustLevelsTool::slotAdjustMaxOutputSpinBox(double val)
00505 {
00506     d->maxOutput->blockSignals(true);
00507     int newVal = (int)(val*d->histoSegments);
00508     d->maxOutput->setValue(newVal);
00509     d->maxOutput->blockSignals(false);
00510     slotAdjustSliders();
00511 }
00512 
00513 void AdjustLevelsTool::slotAdjustSliders()
00514 {
00515     adjustSliders(d->minInput->value(), d->gammaInput->value(),
00516                   d->maxInput->value(), d->minOutput->value(),
00517                   d->maxOutput->value());
00518 }
00519 
00520 void AdjustLevelsTool::adjustSlidersAndSpinboxes(int minIn, double gamIn, int maxIn, int minOut, int maxOut)
00521 {
00522     d->minInput->setValue(minIn);
00523     d->maxInput->setValue(maxIn);
00524     d->minOutput->setValue(minOut);
00525     d->maxOutput->setValue(maxOut);
00526 
00527     adjustSliders(minIn, gamIn, maxIn, minOut, maxOut);
00528 }
00529 
00530 void AdjustLevelsTool::adjustSliders(int minIn, double gamIn, int maxIn, int minOut, int maxOut)
00531 {
00532     d->inputLevels->blockSignals(true);
00533     d->outputLevels->blockSignals(true);
00534 
00535     d->inputLevels->setLeftValue((double)minIn/(double)d->histoSegments);
00536     d->inputLevels->setRightValue((double)maxIn/(double)d->histoSegments);
00537     d->gammaInput->setValue(gamIn);
00538     d->outputLevels->setLeftValue((double)minOut/(double)d->histoSegments);
00539     d->outputLevels->setRightValue((double)maxOut/(double)d->histoSegments);
00540 
00541     d->levels->setLevelLowInputValue(d->gboxSettings->histogramBox()->channel(), minIn);
00542     d->levels->setLevelHighInputValue(d->gboxSettings->histogramBox()->channel(), maxIn);
00543     d->levels->setLevelLowOutputValue(d->gboxSettings->histogramBox()->channel(), minOut);
00544     d->levels->setLevelHighOutputValue(d->gboxSettings->histogramBox()->channel(), maxOut);
00545 
00546     d->inputLevels->blockSignals(false);
00547     d->outputLevels->blockSignals(false);
00548 
00549     slotTimer();
00550 }
00551 
00552 void AdjustLevelsTool::slotResetCurrentChannel()
00553 {
00554     d->levels->levelsChannelReset(d->gboxSettings->histogramBox()->channel());
00555 
00556     // Refresh the current levels config.
00557     slotChannelChanged();
00558     d->levelsHistogramWidget->reset();
00559 
00560     slotEffect();
00561     d->gboxSettings->histogramBox()->histogram()->reset();
00562 }
00563 
00564 void AdjustLevelsTool::slotAutoLevels()
00565 {
00566     // Calculate Auto levels.
00567     d->levels->levelsAuto(d->levelsHistogramWidget->m_imageHistogram);
00568 
00569     // Refresh the current levels config.
00570     slotChannelChanged();
00571 
00572     slotEffect();
00573 }
00574 
00575 void AdjustLevelsTool::slotEffect()
00576 {
00577     ImageIface* iface = d->previewWidget->imageIface();
00578     uchar *orgData    = iface->getPreviewImage();
00579     int w             = iface->previewWidth();
00580     int h             = iface->previewHeight();
00581     bool sb           = iface->previewSixteenBit();
00582 
00583     // Create the new empty destination image data space.
00584     d->gboxSettings->histogramBox()->histogram()->stopHistogramComputation();
00585 
00586     if (d->destinationPreviewData)
00587        delete [] d->destinationPreviewData;
00588 
00589     d->destinationPreviewData = new uchar[w*h*(sb ? 8 : 4)];
00590 
00591     // Calculate the LUT to apply on the image.
00592     d->levels->levelsLutSetup(AlphaChannel);
00593 
00594     // Apply the lut to the image.
00595     d->levels->levelsLutProcess(orgData, d->destinationPreviewData, w, h);
00596 
00597     iface->putPreviewImage(d->destinationPreviewData);
00598     d->previewWidget->updatePreview();
00599 
00600     // Update histogram.
00601     d->gboxSettings->histogramBox()->histogram()->updateData(d->destinationPreviewData, w, h, sb, 0, 0, 0, false);
00602 
00603     delete [] orgData;
00604 }
00605 
00606 void AdjustLevelsTool::finalRendering()
00607 {
00608     kapp->setOverrideCursor( Qt::WaitCursor );
00609     ImageIface* iface = d->previewWidget->imageIface();
00610     uchar *orgData    = iface->getOriginalImage();
00611     int w             = iface->originalWidth();
00612     int h             = iface->originalHeight();
00613     bool sb           = iface->originalSixteenBit();
00614 
00615     // Create the new empty destination image data space.
00616     uchar* desData = new uchar[w*h*(sb ? 8 : 4)];
00617 
00618     // Calculate the LUT to apply on the image.
00619     d->levels->levelsLutSetup(AlphaChannel);
00620 
00621     // Apply the lut to the image.
00622     d->levels->levelsLutProcess(orgData, desData, w, h);
00623 
00624     iface->putOriginalImage(i18n("Adjust Level"), desData);
00625     kapp->restoreOverrideCursor();
00626 
00627     delete [] orgData;
00628     delete [] desData;
00629 }
00630 
00631 void AdjustLevelsTool::slotChannelChanged()
00632 {
00633     int channel = d->gboxSettings->histogramBox()->channel();
00634     switch (channel)
00635     {
00636         case LuminosityChannel:
00637             d->levelsHistogramWidget->m_channelType = LuminosityChannel;
00638             d->inputLevels->setColors(QColor("black"), QColor("white"));
00639             d->inputLevels->setColors(QColor("black"), QColor("white"));
00640             d->outputLevels->setColors(QColor("black"), QColor("white"));
00641             d->outputLevels->setColors(QColor("black"), QColor("white"));
00642             break;
00643 
00644         case RedChannel:
00645             d->levelsHistogramWidget->m_channelType = RedChannel;
00646             d->inputLevels->setColors(QColor("black"), QColor("red"));
00647             d->inputLevels->setColors(QColor("black"), QColor("red"));
00648             d->outputLevels->setColors(QColor("black"), QColor("red"));
00649             d->outputLevels->setColors(QColor("black"), QColor("red"));
00650             break;
00651 
00652         case GreenChannel:
00653             d->levelsHistogramWidget->m_channelType = GreenChannel;
00654             d->inputLevels->setColors(QColor("black"), QColor("green"));
00655             d->inputLevels->setColors(QColor("black"), QColor("green"));
00656             d->outputLevels->setColors(QColor("black"), QColor("green"));
00657             d->outputLevels->setColors(QColor("black"), QColor("green"));
00658             break;
00659 
00660         case BlueChannel:
00661             d->levelsHistogramWidget->m_channelType = BlueChannel;
00662             d->inputLevels->setColors(QColor("black"), QColor("blue"));
00663             d->inputLevels->setColors(QColor("black"), QColor("blue"));
00664             d->outputLevels->setColors(QColor("black"), QColor("blue"));
00665             d->outputLevels->setColors(QColor("black"), QColor("blue"));
00666             break;
00667 
00668         case AlphaChannel:
00669             d->levelsHistogramWidget->m_channelType = AlphaChannel;
00670             d->inputLevels->setColors(QColor("black"), QColor("white"));
00671             d->inputLevels->setColors(QColor("black"), QColor("white"));
00672             d->outputLevels->setColors(QColor("black"), QColor("white"));
00673             d->outputLevels->setColors(QColor("black"), QColor("white"));
00674             break;
00675     }
00676 
00677     adjustSlidersAndSpinboxes(d->levels->getLevelLowInputValue(channel),
00678                               d->levels->getLevelGammaValue(channel),
00679                               d->levels->getLevelHighInputValue(channel),
00680                               d->levels->getLevelLowOutputValue(channel),
00681                               d->levels->getLevelHighOutputValue(channel));
00682 
00683     d->levelsHistogramWidget->repaint();
00684     d->gboxSettings->histogramBox()->slotChannelChanged();
00685 }
00686 
00687 void AdjustLevelsTool::slotScaleChanged()
00688 {
00689     d->levelsHistogramWidget->m_scaleType = d->gboxSettings->histogramBox()->scale();
00690     d->levelsHistogramWidget->repaint();
00691 }
00692 
00693 void AdjustLevelsTool::readSettings()
00694 {
00695     KSharedConfig::Ptr config = KGlobal::config();
00696     KConfigGroup group        = config->group(d->configGroupName);
00697 
00698     {
00699         bool sb        = d->originalImage->sixteenBit();
00700         int max        = sb ? 65535 : 255;
00701         double gamma   = 0.0;
00702         int lowInput   = 0;
00703         int lowOutput  = 0;
00704         int highInput  = 0;
00705         int highOutput = 0;
00706 
00707         for (int i = 0 ; i < 5 ; ++i)
00708         {
00709             gamma      = group.readEntry(d->configGammaChannelEntry.arg(i), 1.0);
00710             lowInput   = group.readEntry(d->configLowInputChannelEntry.arg(i), 0);
00711             lowOutput  = group.readEntry(d->configLowOutputChannelEntry.arg(i), 0);
00712             highInput  = group.readEntry(d->configHighInputChannelEntry.arg(i), max);
00713             highOutput = group.readEntry(d->configHighOutputChannelEntry.arg(i), max);
00714 
00715             d->levels->setLevelGammaValue(i, gamma);
00716             d->levels->setLevelLowInputValue(i, sb ? lowInput*255 : lowInput);
00717             d->levels->setLevelHighInputValue(i, sb ? highInput*255 : highInput);
00718             d->levels->setLevelLowOutputValue(i, sb ? lowOutput*255 : lowOutput);
00719             d->levels->setLevelHighOutputValue(i, sb ? highOutput*255 : highOutput);
00720         }
00721     }
00722 
00723     d->levelsHistogramWidget->reset();
00724     d->gboxSettings->histogramBox()->histogram()->reset();
00725 
00726     d->gboxSettings->histogramBox()->setChannel(group.readEntry(d->configHistogramChannelEntry,
00727                     (int)LuminosityChannel));
00728     d->gboxSettings->histogramBox()->setScale((HistogramScale)group.readEntry(d->configHistogramScaleEntry,
00729                     (int)LogScaleHistogram));
00730 
00731     // This is mandatory here to set spinbox values because slot connections
00732     // can be not set completely at plugin startup.
00733     d->minInput->setValue(d->levels->getLevelLowInputValue(d->gboxSettings->histogramBox()->channel()));
00734     d->minOutput->setValue(d->levels->getLevelLowOutputValue(d->gboxSettings->histogramBox()->channel()));
00735     d->maxInput->setValue(d->levels->getLevelHighInputValue(d->gboxSettings->histogramBox()->channel()));
00736     d->maxOutput->setValue(d->levels->getLevelHighOutputValue(d->gboxSettings->histogramBox()->channel()));
00737     slotChannelChanged();
00738 }
00739 
00740 void AdjustLevelsTool::writeSettings()
00741 {
00742     KSharedConfig::Ptr config = KGlobal::config();
00743     KConfigGroup group        = config->group(d->configGroupName);
00744     group.writeEntry(d->configHistogramChannelEntry, d->gboxSettings->histogramBox()->channel());
00745     group.writeEntry(d->configHistogramScaleEntry,   (int)d->gboxSettings->histogramBox()->scale());
00746 
00747     {
00748         bool sb        = d->originalImage->sixteenBit();
00749         double gamma   = 0.0;
00750         int lowInput   = 0;
00751         int lowOutput  = 0;
00752         int highInput  = 0;
00753         int highOutput = 0;
00754 
00755         for (int i = 0 ; i < 5 ; ++i)
00756         {
00757             gamma      = d->levels->getLevelGammaValue(i);
00758             lowInput   = d->levels->getLevelLowInputValue(i);
00759             lowOutput  = d->levels->getLevelLowOutputValue(i);
00760             highInput  = d->levels->getLevelHighInputValue(i);
00761             highOutput = d->levels->getLevelHighOutputValue(i);
00762 
00763             group.writeEntry(d->configGammaChannelEntry.arg(i), gamma);
00764             group.writeEntry(d->configLowInputChannelEntry.arg(i), sb ? lowInput/255 : lowInput);
00765             group.writeEntry(d->configLowOutputChannelEntry.arg(i), sb ? lowOutput/255 : lowOutput);
00766             group.writeEntry(d->configHighInputChannelEntry.arg(i), sb ? highInput/255 : highInput);
00767             group.writeEntry(d->configHighOutputChannelEntry.arg(i), sb ? highOutput/255 : highOutput);
00768         }
00769     }
00770 
00771     d->previewWidget->writeSettings();
00772 
00773     config->sync();
00774 }
00775 
00776 void AdjustLevelsTool::slotResetSettings()
00777 {
00778     for (int channel = 0 ; channel < 5 ; ++channel)
00779        d->levels->levelsChannelReset(channel);
00780 
00781     // Refresh the current levels config.
00782     slotChannelChanged();
00783     d->levelsHistogramWidget->reset();
00784     d->gboxSettings->histogramBox()->histogram()->reset();
00785 }
00786 
00787 void AdjustLevelsTool::slotLoadSettings()
00788 {
00789     KUrl loadLevelsFile;
00790 
00791     loadLevelsFile = KFileDialog::getOpenUrl(KGlobalSettings::documentPath(),
00792                                              QString( "*" ), kapp->activeWindow(),
00793                                              QString( i18n("Select Gimp Levels File to Load")) );
00794     if ( loadLevelsFile.isEmpty() )
00795        return;
00796 
00797     if ( d->levels->loadLevelsFromGimpLevelsFile( loadLevelsFile ) == false )
00798     {
00799        KMessageBox::error(kapp->activeWindow(),
00800                           i18n("Cannot load from the Gimp levels text file."));
00801        return;
00802     }
00803 
00804     // Refresh the current levels config.
00805     slotChannelChanged();
00806 }
00807 
00808 void AdjustLevelsTool::slotSaveAsSettings()
00809 {
00810     KUrl saveLevelsFile;
00811 
00812     saveLevelsFile = KFileDialog::getSaveUrl(KGlobalSettings::documentPath(),
00813                                              QString( "*" ), kapp->activeWindow(),
00814                                              QString( i18n("Gimp Levels File to Save")) );
00815     if ( saveLevelsFile.isEmpty() )
00816        return;
00817 
00818     if ( d->levels->saveLevelsToGimpLevelsFile( saveLevelsFile ) == false )
00819     {
00820        KMessageBox::error(kapp->activeWindow(),
00821                           i18n("Cannot save to the Gimp levels text file."));
00822        return;
00823     }
00824 
00825     // Refresh the current levels config.
00826     slotChannelChanged();
00827 }
00828 
00829 // See B.K.O #146636: use event filter with all level slider to display a
00830 // guide over level histogram.
00831 bool AdjustLevelsTool::eventFilter(QObject *obj, QEvent *ev)
00832 {
00833     if ( obj == d->inputLevels )
00834     {
00835         if ( ev->type() == QEvent::MouseButtonPress)
00836         {
00837             connect(d->inputLevels, SIGNAL(leftValueChanged(double)),
00838                     this, SLOT(slotShowInputHistogramGuide(double)));
00839 
00840             connect(d->inputLevels, SIGNAL(rightValueChanged(double)),
00841                     this, SLOT(slotShowInputHistogramGuide(double)));
00842 
00843             return false;
00844         }
00845         if ( ev->type() == QEvent::MouseButtonRelease)
00846         {
00847             disconnect(d->inputLevels, SIGNAL(leftValueChanged(double)),
00848                        this, SLOT(slotShowInputHistogramGuide(double)));
00849 
00850             disconnect(d->inputLevels, SIGNAL(rightValueChanged(double)),
00851                        this, SLOT(slotShowInputHistogramGuide(double)));
00852 
00853             d->levelsHistogramWidget->reset();
00854             return false;
00855         }
00856         else
00857         {
00858             return false;
00859         }
00860     }
00861     if ( obj == d->outputLevels )
00862     {
00863         if ( ev->type() == QEvent::MouseButtonPress)
00864         {
00865             connect(d->outputLevels, SIGNAL(leftValueChanged(double)),
00866                     this, SLOT(slotShowOutputHistogramGuide(double)));
00867 
00868             connect(d->outputLevels, SIGNAL(rightValueChanged(double)),
00869                     this, SLOT(slotShowOutputHistogramGuide(double)));
00870 
00871             return false;
00872         }
00873         if ( ev->type() == QEvent::MouseButtonRelease)
00874         {
00875             disconnect(d->outputLevels, SIGNAL(leftValueChanged(double)),
00876                        this, SLOT(slotShowOutputHistogramGuide(double)));
00877 
00878             disconnect(d->outputLevels, SIGNAL(rightValueChanged(double)),
00879                        this, SLOT(slotShowOutputHistogramGuide(double)));
00880 
00881             d->gboxSettings->histogramBox()->histogram()->reset();
00882             return false;
00883         }
00884         else
00885         {
00886             return false;
00887         }
00888     }
00889     else
00890     {
00891         // pass the event on to the parent class
00892         return EditorTool::eventFilter(obj, ev);
00893     }
00894 }
00895 
00896 void AdjustLevelsTool::slotShowInputHistogramGuide(double v)
00897 {
00898     int val = (int)(v * d->histoSegments);
00899     DColor color(val, val, val, val, d->originalImage->sixteenBit());
00900     d->levelsHistogramWidget->setHistogramGuideByColor(color);
00901 }
00902 
00903 void AdjustLevelsTool::slotShowOutputHistogramGuide(double v)
00904 {
00905     int val = (int)(v * d->histoSegments);
00906     DColor color(val, val, val, val, d->originalImage->sixteenBit());
00907     d->gboxSettings->histogramBox()->histogram()->setHistogramGuideByColor(color);
00908 }
00909 
00910 }  // namespace DigikamAdjustLevelsImagesPlugin

digikam

Skip menu "digikam"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members

API Reference

Skip menu "API Reference"
  • digikam
Generated for API Reference by doxygen 1.5.9-20090814
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal