00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "adjustcurvestool.moc"
00026
00027
00028
00029 #include <cmath>
00030
00031
00032
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 <QSpinBox>
00043 #include <QTimer>
00044 #include <QToolButton>
00045
00046
00047
00048 #include <kaboutdata.h>
00049 #include <kapplication.h>
00050 #include <kcombobox.h>
00051 #include <kconfig.h>
00052 #include <kcursor.h>
00053 #include <kfiledialog.h>
00054 #include <kglobal.h>
00055 #include <kglobalsettings.h>
00056 #include <khelpmenu.h>
00057 #include <kicon.h>
00058 #include <kiconloader.h>
00059 #include <klocale.h>
00060 #include <kmenu.h>
00061 #include <kmessagebox.h>
00062 #include <kselector.h>
00063 #include <kstandarddirs.h>
00064
00065
00066
00067 #include "colorgradientwidget.h"
00068 #include "curveswidget.h"
00069 #include "curvesbox.h"
00070 #include "daboutdata.h"
00071 #include "dimg.h"
00072 #include "dimgimagefilters.h"
00073 #include "editortoolsettings.h"
00074 #include "histogrambox.h"
00075 #include "histogramwidget.h"
00076 #include "imagecurves.h"
00077 #include "imagehistogram.h"
00078 #include "imageiface.h"
00079 #include "imagewidget.h"
00080 #include "version.h"
00081
00082 using namespace Digikam;
00083
00084 namespace DigikamAdjustCurvesImagesPlugin
00085 {
00086
00087 class AdjustCurvesToolPriv
00088 {
00089 public:
00090
00091 AdjustCurvesToolPriv() :
00092 configGroupName("adjustcurves Tool"),
00093 configHistogramChannelEntry("Histogram Channel"),
00094 configHistogramScaleEntry("Histogram Scale"),
00095 configCurveEntry("AdjustCurves"),
00096 destinationPreviewData(0),
00097 histoSegments(0),
00098 currentPreviewMode(0),
00099 channelCB(0),
00100 curvesBox(0),
00101 previewWidget(0),
00102 originalImage(0),
00103 gboxSettings(0)
00104 {}
00105
00106 const QString configGroupName;
00107 const QString configHistogramChannelEntry;
00108 const QString configHistogramScaleEntry;
00109 const QString configCurveEntry;
00110
00111 uchar* destinationPreviewData;
00112
00113 int histoSegments;
00114 int currentPreviewMode;
00115
00116 KComboBox* channelCB;
00117
00118 CurvesBox* curvesBox;
00119 ImageWidget* previewWidget;
00120
00121 DImg* originalImage;
00122
00123 EditorToolSettings* gboxSettings;
00124 };
00125
00126 AdjustCurvesTool::AdjustCurvesTool(QObject* parent)
00127 : EditorTool(parent),
00128 d(new AdjustCurvesToolPriv)
00129 {
00130 setObjectName("adjustcurves");
00131 setToolName(i18n("Adjust Curves"));
00132 setToolIcon(SmallIcon("adjustcurves"));
00133
00134 d->destinationPreviewData = 0;
00135
00136 ImageIface iface(0, 0);
00137 d->originalImage = iface.getOriginalImg();
00138
00139 d->histoSegments = d->originalImage->sixteenBit() ? 65535 : 255;
00140
00141
00142
00143 d->previewWidget = new ImageWidget("adjustcurves Tool", 0,
00144 i18n("This is the image's curve-adjustments preview. "
00145 "You can pick a spot on the image "
00146 "to see the corresponding level in the histogram."));
00147 setToolView(d->previewWidget);
00148
00149
00150
00151 d->gboxSettings = new EditorToolSettings;
00152 d->gboxSettings->setButtons(EditorToolSettings::Default|
00153 EditorToolSettings::Load|
00154 EditorToolSettings::SaveAs|
00155 EditorToolSettings::Ok|
00156 EditorToolSettings::Cancel);
00157
00158 d->gboxSettings->setTools( EditorToolSettings::Histogram);
00159 d->gboxSettings->setHistogramType(Digikam::LRGBA);
00160
00161 d->gboxSettings->histogramBox()->histogram()->setWhatsThis(i18n("Here you can see the target preview "
00162 "image histogram drawing of the selected image "
00163 "channel. This one is re-computed at any curves "
00164 "settings changes."));
00165
00166
00167 d->gboxSettings->histogramBox()->setGradientVisible(false);
00168
00169
00170
00171 d->curvesBox = new CurvesBox(256, 256, d->originalImage->bits(), d->originalImage->width(),
00172 d->originalImage->height(), d->originalImage->sixteenBit());
00173
00174 d->curvesBox->enableGradients(true);
00175 d->curvesBox->enableControlWidgets(true);
00176
00177
00178
00179 QGridLayout* mainLayout = new QGridLayout();
00180 mainLayout->addWidget(d->curvesBox, 0, 0, 1, 1);
00181 mainLayout->setRowStretch(1, 10);
00182 mainLayout->setMargin(0);
00183 mainLayout->setSpacing(d->gboxSettings->spacingHint());
00184 d->gboxSettings->plainPage()->setLayout(mainLayout);
00185
00186
00187
00188 setToolSettings(d->gboxSettings);
00189 init();
00190
00191
00192
00193 connect(d->curvesBox, SIGNAL(signalCurvesChanged()),
00194 this, SLOT(slotTimer()));
00195
00196 connect(d->previewWidget, SIGNAL(spotPositionChangedFromOriginal( const Digikam::DColor &, const QPoint & )),
00197 this, SLOT(slotSpotColorChanged( const Digikam::DColor & )));
00198
00199 connect(d->previewWidget, SIGNAL(spotPositionChangedFromTarget( const Digikam::DColor &, const QPoint & )),
00200 this, SLOT(slotColorSelectedFromTarget( const Digikam::DColor & )));
00201
00202 connect(d->previewWidget, SIGNAL(signalResized()),
00203 this, SLOT(slotEffect()));
00204
00205
00206
00207
00208 connect(d->curvesBox, SIGNAL(signalChannelReset(int)),
00209 this, SLOT(slotResetCurrentChannel()));
00210
00211 connect(d->curvesBox, SIGNAL(signalPickerChanged(int)),
00212 this, SLOT(slotPickerColorButtonActived()));
00213 }
00214
00215 AdjustCurvesTool::~AdjustCurvesTool()
00216 {
00217 delete [] d->destinationPreviewData;
00218 delete d;
00219 }
00220
00221 void AdjustCurvesTool::slotPickerColorButtonActived()
00222 {
00223
00224 d->currentPreviewMode = d->previewWidget->getRenderingPreviewMode();
00225 d->previewWidget->setRenderingPreviewMode(ImageGuideWidget::PreviewOriginalImage);
00226 }
00227
00228 void AdjustCurvesTool::slotSpotColorChanged(const DColor& color)
00229 {
00230 DColor sc = color;
00231
00232 switch (d->curvesBox->picker())
00233 {
00234 case CurvesBox::BlackTonal:
00235 {
00236
00237 d->curvesBox->curves()->setCurvePoint(LuminosityChannel, 1,
00238 QPoint(qMax(qMax(sc.red(), sc.green()), sc.blue()), 42*d->histoSegments/256));
00239 d->curvesBox->curves()->setCurvePoint(RedChannel, 1, QPoint(sc.red(), 42*d->histoSegments/256));
00240 d->curvesBox->curves()->setCurvePoint(GreenChannel, 1, QPoint(sc.green(), 42*d->histoSegments/256));
00241 d->curvesBox->curves()->setCurvePoint(BlueChannel, 1, QPoint(sc.blue(), 42*d->histoSegments/256));
00242 d->curvesBox->resetPickers();
00243 break;
00244 }
00245 case CurvesBox::GrayTonal:
00246 {
00247
00248 d->curvesBox->curves()->setCurvePoint(LuminosityChannel, 8,
00249 QPoint(qMax(qMax(sc.red(), sc.green()), sc.blue()), 128*d->histoSegments/256));
00250 d->curvesBox->curves()->setCurvePoint(RedChannel, 8, QPoint(sc.red(), 128*d->histoSegments/256));
00251 d->curvesBox->curves()->setCurvePoint(GreenChannel, 8, QPoint(sc.green(), 128*d->histoSegments/256));
00252 d->curvesBox->curves()->setCurvePoint(BlueChannel, 8, QPoint(sc.blue(), 128*d->histoSegments/256));
00253 d->curvesBox->resetPickers();
00254 break;
00255 }
00256 case CurvesBox::WhiteTonal:
00257 {
00258
00259 d->curvesBox->curves()->setCurvePoint(LuminosityChannel, 15,
00260 QPoint(qMax(qMax(sc.red(), sc.green()), sc.blue()), 213*d->histoSegments/256));
00261 d->curvesBox->curves()->setCurvePoint(RedChannel, 15, QPoint(sc.red(), 213*d->histoSegments/256));
00262 d->curvesBox->curves()->setCurvePoint(GreenChannel, 15, QPoint(sc.green(), 213*d->histoSegments/256));
00263 d->curvesBox->curves()->setCurvePoint(BlueChannel, 15, QPoint(sc.blue(), 213*d->histoSegments/256));
00264 d->curvesBox->resetPickers();
00265 break;
00266 }
00267 default:
00268 {
00269 d->curvesBox->setCurveGuide(color);
00270 return;
00271 }
00272 }
00273
00274
00275
00276 for (int i = LuminosityChannel ; i <= BlueChannel ; ++i)
00277 d->curvesBox->curves()->curvesCalculateCurve(i);
00278
00279 d->curvesBox->repaint();
00280
00281
00282 d->previewWidget->setRenderingPreviewMode(d->currentPreviewMode);
00283
00284 slotEffect();
00285 }
00286
00287 void AdjustCurvesTool::slotColorSelectedFromTarget( const DColor& color )
00288 {
00289 d->gboxSettings->histogramBox()->histogram()->setHistogramGuideByColor(color);
00290 }
00291
00292 void AdjustCurvesTool::slotResetCurrentChannel()
00293 {
00294 slotEffect();
00295 d->gboxSettings->histogramBox()->histogram()->reset();
00296 }
00297
00298 void AdjustCurvesTool::slotEffect()
00299 {
00300 ImageIface* iface = d->previewWidget->imageIface();
00301 uchar *orgData = iface->getPreviewImage();
00302 int w = iface->previewWidth();
00303 int h = iface->previewHeight();
00304 bool sb = iface->previewSixteenBit();
00305
00306
00307 d->gboxSettings->histogramBox()->histogram()->stopHistogramComputation();
00308
00309 if (d->destinationPreviewData)
00310 delete [] d->destinationPreviewData;
00311
00312 d->destinationPreviewData = new uchar[w*h*(sb ? 8 : 4)];
00313
00314
00315 d->curvesBox->curves()->curvesLutSetup(AlphaChannel);
00316
00317
00318 d->curvesBox->curves()->curvesLutProcess(orgData, d->destinationPreviewData, w, h);
00319
00320 iface->putPreviewImage(d->destinationPreviewData);
00321 d->previewWidget->updatePreview();
00322
00323
00324 d->gboxSettings->histogramBox()->histogram()->updateData(d->destinationPreviewData, w, h, sb, 0, 0, 0, false);
00325 delete [] orgData;
00326 }
00327
00328 void AdjustCurvesTool::finalRendering()
00329 {
00330 kapp->setOverrideCursor( Qt::WaitCursor );
00331
00332 ImageIface* iface = d->previewWidget->imageIface();
00333 uchar *orgData = iface->getOriginalImage();
00334 int w = iface->originalWidth();
00335 int h = iface->originalHeight();
00336 bool sb = iface->originalSixteenBit();
00337
00338
00339 uchar* desData = new uchar[w*h*(sb ? 8 : 4)];
00340
00341
00342 d->curvesBox->curves()->curvesLutSetup(AlphaChannel);
00343
00344
00345 d->curvesBox->curves()->curvesLutProcess(orgData, desData, w, h);
00346
00347 iface->putOriginalImage(i18n("Adjust Curve"), desData);
00348 kapp->restoreOverrideCursor();
00349
00350 delete [] orgData;
00351 delete [] desData;
00352 }
00353
00354 void AdjustCurvesTool::slotChannelChanged()
00355 {
00356 d->curvesBox->setChannel(d->gboxSettings->histogramBox()->channel());
00357 d->gboxSettings->histogramBox()->slotChannelChanged();
00358 }
00359
00360 void AdjustCurvesTool::slotScaleChanged()
00361 {
00362 d->curvesBox->setScale(d->gboxSettings->histogramBox()->scale());
00363 }
00364
00365 void AdjustCurvesTool::readSettings()
00366 {
00367 KSharedConfig::Ptr config = KGlobal::config();
00368 KConfigGroup group = config->group(d->configGroupName);
00369
00370 d->curvesBox->reset();
00371 d->curvesBox->readCurveSettings(group, d->configCurveEntry);
00372
00373
00374 d->gboxSettings->histogramBox()->setChannel(group.readEntry(d->configHistogramChannelEntry,
00375 (int)LuminosityChannel));
00376 d->gboxSettings->histogramBox()->setScale((HistogramScale)group.readEntry(d->configHistogramScaleEntry,
00377 (int)LogScaleHistogram));
00378
00379 d->curvesBox->setScale(d->gboxSettings->histogramBox()->scale());
00380 d->curvesBox->setChannel(d->gboxSettings->histogramBox()->channel());
00381 d->curvesBox->update();
00382
00383 slotEffect();
00384 }
00385
00386 void AdjustCurvesTool::writeSettings()
00387 {
00388 KSharedConfig::Ptr config = KGlobal::config();
00389 KConfigGroup group = config->group(d->configGroupName);
00390 group.writeEntry(d->configHistogramChannelEntry, d->gboxSettings->histogramBox()->channel());
00391 group.writeEntry(d->configHistogramScaleEntry, (int)d->gboxSettings->histogramBox()->scale());
00392
00393 d->curvesBox->writeCurveSettings(group, d->configCurveEntry);
00394 d->previewWidget->writeSettings();
00395
00396 config->sync();
00397 }
00398
00399 void AdjustCurvesTool::slotResetSettings()
00400 {
00401 d->curvesBox->resetChannels();
00402 d->curvesBox->resetPickers();
00403 d->gboxSettings->histogramBox()->histogram()->reset();
00404
00405 slotEffect();
00406 }
00407
00408 void AdjustCurvesTool::slotLoadSettings()
00409 {
00410 KUrl loadCurvesFile;
00411
00412 loadCurvesFile = KFileDialog::getOpenUrl(KGlobalSettings::documentPath(),
00413 QString( "*" ), kapp->activeWindow(),
00414 QString( i18n("Select Gimp Curves File to Load")) );
00415 if ( loadCurvesFile.isEmpty() )
00416 return;
00417
00418 if ( d->curvesBox->curves()->loadCurvesFromGimpCurvesFile( loadCurvesFile ) == false )
00419 {
00420 KMessageBox::error(kapp->activeWindow(),
00421 i18n("Cannot load from the Gimp curves text file."));
00422 return;
00423 }
00424
00425
00426 slotChannelChanged();
00427 slotEffect();
00428 }
00429
00430 void AdjustCurvesTool::slotSaveAsSettings()
00431 {
00432 KUrl saveCurvesFile;
00433
00434 saveCurvesFile = KFileDialog::getSaveUrl(KGlobalSettings::documentPath(),
00435 QString( "*" ), kapp->activeWindow(),
00436 QString( i18n("Gimp Curves File to Save")) );
00437 if ( saveCurvesFile.isEmpty() )
00438 return;
00439
00440 if ( d->curvesBox->curves()->saveCurvesToGimpCurvesFile( saveCurvesFile ) == false )
00441 {
00442 KMessageBox::error(kapp->activeWindow(),
00443 i18n("Cannot save to the Gimp curves text file."));
00444 return;
00445 }
00446
00447
00448 slotChannelChanged();
00449 }
00450
00451 }