[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    [digikam] /: Add Image editor red eyes autocorrection tool as Batch Queue Manager
From:       Gilles Caulier <caulier.gilles () gmail ! com>
Date:       2016-09-11 19:20:26
Message-ID: E1bjAIk-0005FM-70 () code ! kde ! org
[Download RAW message or body]

Git commit 597709193099e6ef40799a4bf56984b7cd6bf9b7 by Gilles Caulier.
Committed on 11/09/2016 at 19:19.
Pushed by cgilles into branch 'master'.

Add Image editor red eyes autocorrection tool as Batch Queue Manager

M  +1    -0    NEWS
M  +1    -0    app/views/welcomepageview.cpp
M  +2    -3    libs/dimg/CMakeLists.txt
M  +1    -1    libs/dimg/filters/README
R  +0    -0    libs/dimg/filters/redeye/redeyecorrectioncontainer.h [from: \
libs/facesengine/redeye/redeyecorrectioncontainer.h - 100% similarity] R  +4    -3    \
libs/dimg/filters/redeye/redeyecorrectionfilter.cpp [from: \
libs/facesengine/redeye/redeyecorrectionfilter.cpp - 099% similarity] R  +0    -0    \
libs/dimg/filters/redeye/redeyecorrectionfilter.h [from: \
libs/facesengine/redeye/redeyecorrectionfilter.h - 100% similarity] R  +0    -0    \
libs/dimg/filters/redeye/redeyecorrectionsettings.cpp [from: \
libs/facesengine/redeye/redeyecorrectionsettings.cpp - 100% similarity] R  +0    -0   \
libs/dimg/filters/redeye/redeyecorrectionsettings.h [from: \
libs/facesengine/redeye/redeyecorrectionsettings.h - 100% similarity] M  +0    -3    \
libs/facesengine/CMakeLists.txt M  +0    -14   \
utilities/imageeditor/editor/editorwindow.cpp M  +1    -1    \
utilities/imageeditor/tools/TODO M  +2    -2    \
utilities/imageeditor/tools/colors/bcgtool.cpp M  +2    -1    \
utilities/imageeditor/tools/enhance/blurtool.cpp M  +45   -433  \
utilities/imageeditor/tools/enhance/redeyetool.cpp M  +5    -8    \
utilities/imageeditor/tools/enhance/redeyetool.h M  +5    -0    \
utilities/imageeditor/widgets/imageregionwidget.cpp M  +2    -0    \
utilities/imageeditor/widgets/imageregionwidget.h

http://commits.kde.org/digikam/597709193099e6ef40799a4bf56984b7cd6bf9b7

diff --git a/NEWS b/NEWS
index e420116..37c4727 100644
--- a/NEWS
+++ b/NEWS
@@ -4,6 +4,7 @@ digiKam 5.2.0 - Release date: 2016-09-11
 NEW FEATURES:
 
 ImageEditor   : digiKam editor and Showfoto plugins interface removed to reduce \
run-time dependancies and speed-up initialization. +ImageEditor   : New tool to \
detect and fix red-eyes automatically.  Import        : New configuration options to \
support gPhoto2 PTP/IP cameras.  BQM           : New tool to detect and fix red-eyes \
automatically.  Setup         : Factoring and simplification of Album and Image \
                Editor tabs.
diff --git a/app/views/welcomepageview.cpp b/app/views/welcomepageview.cpp
index b73e22f..515775f 100644
--- a/app/views/welcomepageview.cpp
+++ b/app/views/welcomepageview.cpp
@@ -94,6 +94,7 @@ QStringList WelcomePageView::featuresTabContent() const
     newFeatures << i18n("Add a new option in editor and light table to edit \
                metadata;");
     newFeatures << i18n("Add a new option in editor and light table to edit \
                geolocation;");
     newFeatures << i18n("Add a new option in editor and light table to run \
presentation tool;"); +    newFeatures << i18n("Add a new editor tool to detect and \
                fix red-eyes automatically;");
     newFeatures << i18n("Add a new editor tool to perform color change based on \
                Lut3D;");
     newFeatures << i18n("Add a new tool in camera import interface to convert RAW \
files to DNG;");  newFeatures << i18n("Consolidation of Mysql database backend;");
diff --git a/libs/dimg/CMakeLists.txt b/libs/dimg/CMakeLists.txt
index 72efc07..6af97ab 100644
--- a/libs/dimg/CMakeLists.txt
+++ b/libs/dimg/CMakeLists.txt
@@ -108,12 +108,12 @@ set(libdimgfilters_SRCS
     filters/lens/antivignettingsettings.cpp
     filters/lens/lensdistortionfilter.cpp
     filters/lens/pixelaccess.cpp
-#    filters/redeye/redeyecorrectionfilter.cpp
+    filters/redeye/redeyecorrectionfilter.cpp
+    filters/redeye/redeyecorrectionsettings.cpp
 )
 
 
 set(facedetector_LIB_SRCS ../facesengine/detection/opencvfacedetector.cpp
-                          ../facesengine/redeye/redeyecorrectionfilter.cpp
                           ../facesengine/facedetector.cpp
 
 )
@@ -202,7 +202,6 @@ include_directories(
 )
 
 include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../facesengine/
-                    ${CMAKE_CURRENT_SOURCE_DIR}/../facesengine/redeye/
                     ${CMAKE_CURRENT_SOURCE_DIR}/../facesengine/detector/
 )
 
diff --git a/libs/dimg/filters/README b/libs/dimg/filters/README
index d6ed1bc..1ca0fca 100644
--- a/libs/dimg/filters/README
+++ b/libs/dimg/filters/README
@@ -16,4 +16,4 @@ nr            : Wavelets Noise Reduction.
 sharp         : Sharp / Unsharp Mask / Refocus
 transform     : Change Image Geometry.
 wb            : White Balance.
-redeye        : Red-Eye Detection and Correction (core/libs/faceengine/redeye)
+redeye        : Red-Eye Detection and Correction.
diff --git a/libs/facesengine/redeye/redeyecorrectioncontainer.h \
b/libs/dimg/filters/redeye/redeyecorrectioncontainer.h similarity index 100%
rename from libs/facesengine/redeye/redeyecorrectioncontainer.h
rename to libs/dimg/filters/redeye/redeyecorrectioncontainer.h
diff --git a/libs/facesengine/redeye/redeyecorrectionfilter.cpp \
b/libs/dimg/filters/redeye/redeyecorrectionfilter.cpp similarity index 99%
rename from libs/facesengine/redeye/redeyecorrectionfilter.cpp
rename to libs/dimg/filters/redeye/redeyecorrectionfilter.cpp
index e19746d..0e32623 100644
--- a/libs/facesengine/redeye/redeyecorrectionfilter.cpp
+++ b/libs/dimg/filters/redeye/redeyecorrectionfilter.cpp
@@ -28,11 +28,12 @@
 
 // Qt includes
 
-#include <QStandardPaths>
+#include <QtConcurrent>
+#include <QtMath>
+#include <QMutex>
 #include <QListIterator>
-#include <QDataStream>
 #include <QImage>
-#include <QFile>
+#include <QDataStream>
 
 // Local includes
 
diff --git a/libs/facesengine/redeye/redeyecorrectionfilter.h \
b/libs/dimg/filters/redeye/redeyecorrectionfilter.h similarity index 100%
rename from libs/facesengine/redeye/redeyecorrectionfilter.h
rename to libs/dimg/filters/redeye/redeyecorrectionfilter.h
diff --git a/libs/facesengine/redeye/redeyecorrectionsettings.cpp \
b/libs/dimg/filters/redeye/redeyecorrectionsettings.cpp similarity index 100%
rename from libs/facesengine/redeye/redeyecorrectionsettings.cpp
rename to libs/dimg/filters/redeye/redeyecorrectionsettings.cpp
diff --git a/libs/facesengine/redeye/redeyecorrectionsettings.h \
b/libs/dimg/filters/redeye/redeyecorrectionsettings.h similarity index 100%
rename from libs/facesengine/redeye/redeyecorrectionsettings.h
rename to libs/dimg/filters/redeye/redeyecorrectionsettings.h
diff --git a/libs/facesengine/CMakeLists.txt b/libs/facesengine/CMakeLists.txt
index d102fbb..54691be 100644
--- a/libs/facesengine/CMakeLists.txt
+++ b/libs/facesengine/CMakeLists.txt
@@ -27,7 +27,6 @@ include_directories(${CMAKE_CURRENT_BINARY_DIR}/..
                     ${CMAKE_CURRENT_SOURCE_DIR}/detection
                     ${CMAKE_CURRENT_SOURCE_DIR}/recognition-opencv-lbph
                     ${CMAKE_CURRENT_SOURCE_DIR}/alignment-congealing
-                    ${CMAKE_CURRENT_SOURCE_DIR}/redeye
                     ${CMAKE_CURRENT_SOURCE_DIR}/shape-predictor
 
 #                   ${CMAKE_CURRENT_SOURCE_DIR}/alignment-flandmark
@@ -50,8 +49,6 @@ set(facesengine_LIB_SRCS detection/opencvfacedetector.cpp
                          recognition-opencv-lbph/opencvlbphfacerecognizer.cpp
                          recognition-opencv-lbph/opencvmatdata.cpp
                          recognition-opencv-lbph/facerec_borrowed.cpp
-                         redeye/redeyecorrectionfilter.cpp
-                         redeye/redeyecorrectionsettings.cpp
                          facedetector.cpp
                          identity.cpp
                          dataproviders.cpp
diff --git a/utilities/imageeditor/editor/editorwindow.cpp \
b/utilities/imageeditor/editor/editorwindow.cpp index 3937814..33fb934 100644
--- a/utilities/imageeditor/editor/editorwindow.cpp
+++ b/utilities/imageeditor/editor/editorwindow.cpp
@@ -3461,20 +3461,6 @@ void EditorWindow::slotLocalContrast()
 
 void EditorWindow::slotRedEye()
 {
-    ImageIface iface;
-
-    if (iface.selectionRect().size().isNull())
-    {
-        EditorToolPassivePopup* const popup = new \
                EditorToolPassivePopup(qApp->activeWindow());
-        popup->setView(i18n("Red-Eye Correction Tool"),
-                       i18n("You need to select a region including the eyes to use "
-                            "the red-eye correction tool"));
-        popup->setAutoDelete(true);
-        popup->setTimeout(2500);
-        popup->show();
-        return;
-    }
-
     loadTool(new RedEyeTool(this));
 }
 
diff --git a/utilities/imageeditor/tools/TODO b/utilities/imageeditor/tools/TODO
index c3e77ff..4549ecd 100644
--- a/utilities/imageeditor/tools/TODO
+++ b/utilities/imageeditor/tools/TODO
@@ -38,7 +38,7 @@ enhance
   /restoration              DONE          TODO             DONE                  \
DONE  /blurtool                 DONE          DONE             DONE                  \
DONE  /localcontrast            DONE          DONE             DONE                  \
                DONE
-  /redeyetool               DONE          TODO             TODO                   NO
+  /redeyetool               DONE          DONE             DONE                  \
DONE  /inpainting               DONE          TODO              NO                    \
NO  /autocorrection           DONE          TODO             DONE                  \
DONE  /distortion               DONE          TODO             TODO                  \
                TODO
diff --git a/utilities/imageeditor/tools/colors/bcgtool.cpp \
b/utilities/imageeditor/tools/colors/bcgtool.cpp index ee082ad..85e97d7 100644
--- a/utilities/imageeditor/tools/colors/bcgtool.cpp
+++ b/utilities/imageeditor/tools/colors/bcgtool.cpp
@@ -58,7 +58,8 @@ public:
         settingsView(0),
         previewWidget(0),
         gboxSettings(0)
-    {}
+    {
+    }
 
     static const QString configGroupName;
     static const QString configHistogramChannelEntry;
@@ -99,7 +100,6 @@ BCGTool::BCGTool(QObject* const parent)
     d->gboxSettings->setButtons(EditorToolSettings::Default|
                                 EditorToolSettings::Ok|
                                 EditorToolSettings::Cancel);
-//                              EditorToolSettings::Try);
 
     // -------------------------------------------------------------
 
diff --git a/utilities/imageeditor/tools/enhance/blurtool.cpp \
b/utilities/imageeditor/tools/enhance/blurtool.cpp index a6a8c14..2383573 100644
--- a/utilities/imageeditor/tools/enhance/blurtool.cpp
+++ b/utilities/imageeditor/tools/enhance/blurtool.cpp
@@ -54,7 +54,8 @@ public:
         radiusInput(0),
         previewWidget(0),
         gboxSettings(0)
-    {}
+    {
+    }
 
     static const QString configGroupName;
     static const QString configRadiusAdjustmentEntry;
diff --git a/utilities/imageeditor/tools/enhance/redeyetool.cpp \
b/utilities/imageeditor/tools/enhance/redeyetool.cpp index 8d07447..89d6be1 100644
--- a/utilities/imageeditor/tools/enhance/redeyetool.cpp
+++ b/utilities/imageeditor/tools/enhance/redeyetool.cpp
@@ -46,17 +46,14 @@
 
 // Local includes
 
-#include "dnuminput.h"
-#include "dcolorvalueselector.h"
-#include "dhuesaturationselect.h"
-#include "colorgradientwidget.h"
 #include "dimg.h"
-#include "blurfilter.h"
 #include "editortoolsettings.h"
 #include "histogramwidget.h"
 #include "histogrambox.h"
 #include "imageiface.h"
-#include "imageguidewidget.h"
+#include "redeyecorrectionfilter.h"
+#include "redeyecorrectionsettings.h"
+#include "imageregionwidget.h"
 
 namespace Digikam
 {
@@ -67,57 +64,29 @@ class RedEyeTool::Private
 public:
 
     Private() :
-        thresholdLabel(0),
-        smoothLabel(0),
-        HSSelector(0),
-        VSelector(0),
-        tintLevel(0),
-        redThreshold(0),
-        smoothLevel(0),
+        settingsView(0),
         previewWidget(0),
         gboxSettings(0)
-    {}
-
-    static const QString    configGroupName;
-    static const QString    configHistogramChannelEntry;
-    static const QString    configHistogramScaleEntry;
-    static const QString    configRedThresholdEntry;
-    static const QString    configSmoothLevelEntry;
-    static const QString    configHueColoringTintEntry;
-    static const QString    configSatColoringTintEntry;
-    static const QString    configValColoringTintEntry;
-    static const QString    configTintLevelEntry;
-
-    QColor                  selColor;
-
-    QLabel*                 thresholdLabel;
-    QLabel*                 smoothLabel;
-
-    DHueSaturationSelector* HSSelector;
-    DColorValueSelector*    VSelector;
+    {
+    }
 
-    DIntNumInput*           tintLevel;
-    DIntNumInput*           redThreshold;
-    DIntNumInput*           smoothLevel;
+    static const QString      configGroupName;
+    static const QString      configHistogramChannelEntry;
+    static const QString      configHistogramScaleEntry;
 
-    ImageGuideWidget*       previewWidget;
-    EditorToolSettings*     gboxSettings;
+    RedEyeCorrectionSettings* settingsView;
+    ImageRegionWidget*        previewWidget;
+    EditorToolSettings*       gboxSettings;
 };
 
 const QString RedEyeTool::Private::configGroupName(QLatin1String("redeye Tool"));
 const QString RedEyeTool::Private::configHistogramChannelEntry(QLatin1String("Histogram \
Channel"));  const QString \
                RedEyeTool::Private::configHistogramScaleEntry(QLatin1String("Histogram \
                Scale"));
-const QString RedEyeTool::Private::configRedThresholdEntry(QLatin1String("RedThreshold"));
                
-const QString RedEyeTool::Private::configSmoothLevelEntry(QLatin1String("SmoothLevel"));
                
-const QString RedEyeTool::Private::configHueColoringTintEntry(QLatin1String("HueColoringTint"));
                
-const QString RedEyeTool::Private::configSatColoringTintEntry(QLatin1String("SatColoringTint"));
                
-const QString RedEyeTool::Private::configValColoringTintEntry(QLatin1String("ValColoringTint"));
                
-const QString RedEyeTool::Private::configTintLevelEntry(QLatin1String("TintLevel"));
 
 // --------------------------------------------------------
 
 RedEyeTool::RedEyeTool(QObject* const parent)
-    : EditorTool(parent),
+    : EditorToolThreaded(parent),
       d(new Private)
 {
     setObjectName(QLatin1String("redeye"));
@@ -125,98 +94,28 @@ RedEyeTool::RedEyeTool(QObject* const parent)
     setToolIcon(QIcon::fromTheme(QLatin1String("redeyes")));
     setToolHelp(QLatin1String("redeyecorrectiontool.anchor"));
 
-    d->previewWidget = new ImageGuideWidget(0, true, \
ImageGuideWidget::PickColorMode, Qt::red, 1, false, ImageIface::ImageSelection); +    \
                d->previewWidget = new ImageRegionWidget;
     d->previewWidget->setToolTip(i18n("Here you can see the image selection preview \
with "  "red eye reduction applied."));
-    setToolView(d->previewWidget);
-    setPreviewModeMask(PreviewToolBar::AllPreviewModes);
 
     // -------------------------------------------------------------
 
     d->gboxSettings = new EditorToolSettings;
     d->gboxSettings->setTools(EditorToolSettings::Histogram);
+    d->gboxSettings->setHistogramType(LRGBC);
+    d->gboxSettings->setButtons(EditorToolSettings::Default|
+                                EditorToolSettings::Ok|
+                                EditorToolSettings::Cancel);
 
-    // -------------------------------------------------------------
-
-    d->thresholdLabel = new QLabel(i18n("Sensitivity:"));
-    d->redThreshold   = new DIntNumInput();
-    d->redThreshold->setRange(10, 90, 1);
-    d->redThreshold->setDefaultValue(20);
-    d->redThreshold->setWhatsThis(i18n("<p>Control the red pixel selection \
                threshold.</p>"
-                                       "<p>Low values will select more red pixels "
-                                       "(aggressive correction), high values will \
                select fewer (mild correction). "
-                                       "Use a low value if an eye has been selected \
                exactly. "
-                                       "Use a high value if other parts of the face \
                have been selected too.</p>"));
-
-    d->smoothLabel = new QLabel(i18nc("Smoothness when blurring border of changed \
                pixels", "Smooth:"));
-    d->smoothLevel = new DIntNumInput();
-    d->smoothLevel->setRange(0, 5, 1);
-    d->smoothLevel->setDefaultValue(1);
-    d->smoothLevel->setWhatsThis(i18n("Sets the smoothness value when blurring the \
                border "
-                                      "of the changed pixels. "
-                                      "This leads to a more naturally looking \
                pupil."));
-
-    QLabel* const label3 = new QLabel(i18n("Coloring Tint:"));
-    d->HSSelector        = new DHueSaturationSelector();
-    d->HSSelector->setWhatsThis(i18n("Sets a custom color when re-colorizing the \
                eyes."));
-    d->HSSelector->setMinimumSize(200, 142);
-    d->HSSelector->setChooserMode(ChooserValue);
-    d->HSSelector->setColorValue(255);
-
-    d->VSelector          = new DColorValueSelector();
-    d->VSelector->setChooserMode(ChooserValue);
-    d->VSelector->setMinimumSize(26, 142);
-    d->VSelector->setIndent(false);
-
-    QLabel* const label4 = new QLabel(i18n("Tint Level:"));
-    d->tintLevel         = new DIntNumInput();
-    d->tintLevel->setRange(1, 200, 1);
-    d->tintLevel->setDefaultValue(128);
-    d->tintLevel->setWhatsThis(i18n("Set the tint level to adjust the luminosity of \
                "
-                                    "the new color of the pupil."));
-
-    // -------------------------------------------------------------
-
-    const int spacing = d->gboxSettings->spacingHint();
-
-    QGridLayout* const mainLayout = new QGridLayout();
-    mainLayout->addWidget(d->thresholdLabel, 0, 0, 1, 5);
-    mainLayout->addWidget(d->redThreshold,   1, 0, 1, 5);
-    mainLayout->addWidget(d->smoothLabel,    2, 0, 1, 5);
-    mainLayout->addWidget(d->smoothLevel,    3, 0, 1, 5);
-    mainLayout->addWidget(label3,            4, 0, 1, 5);
-    mainLayout->addWidget(d->HSSelector,     5, 0, 1, 4);
-    mainLayout->addWidget(d->VSelector,      5, 4, 1, 1);
-    mainLayout->addWidget(label4,            6, 0, 1, 5);
-    mainLayout->addWidget(d->tintLevel,      7, 0, 1, 5);
-    mainLayout->setRowStretch(8, 10);
-    mainLayout->setColumnStretch(3, 10);
-    mainLayout->setContentsMargins(spacing, spacing, spacing, spacing);
-    mainLayout->setSpacing(spacing);
-    d->gboxSettings->plainPage()->setLayout(mainLayout);
-
-    // -------------------------------------------------------------
+    d->settingsView = new RedEyeCorrectionSettings(d->gboxSettings->plainPage());
 
+    setToolView(d->previewWidget);
+    setPreviewModeMask(PreviewToolBar::AllPreviewModes);
     setToolSettings(d->gboxSettings);
 
     // -------------------------------------------------------------
-/*
-    connect(d->previewWidget, \
                SIGNAL(spotPositionChangedFromTarget(Digikam::DColor,QPoint)),
-            this, SLOT(slotColorSelectedFromTarget(Digikam::DColor)));
-*/
-    connect(d->redThreshold, SIGNAL(valueChanged(int)),
-            this, SLOT(slotTimer()));
-
-    connect(d->smoothLevel, SIGNAL(valueChanged(int)),
-            this, SLOT(slotTimer()));
-
-    connect(d->HSSelector, SIGNAL(valueChanged(int,int)),
-            this, SLOT(slotHSChanged(int,int)));
 
-    connect(d->VSelector, SIGNAL(valueChanged(int)),
-            this, SLOT(slotVChanged(int)));
-
-    connect(d->tintLevel, SIGNAL(valueChanged(int)),
+    connect(d->settingsView, SIGNAL(signalSettingsChanged()),
             this, SLOT(slotTimer()));
 }
 
@@ -225,354 +124,67 @@ RedEyeTool::~RedEyeTool()
     delete d;
 }
 
-void RedEyeTool::slotHSChanged(int h, int s)
-{
-    QColor color;
-
-    int val = d->selColor.value();
-
-    color.setHsv(h, s, val);
-    setColor(color);
-}
-
-void RedEyeTool::slotVChanged(int v)
-{
-    QColor color;
-
-    int hue = d->selColor.hue();
-    int sat = d->selColor.saturation();
-
-    color.setHsv(hue, sat, v);
-    setColor(color);
-}
-
-void RedEyeTool::setColor(const QColor& color)
-{
-    if (color.isValid())
-    {
-        d->selColor = color;
-
-        // set values
-        d->HSSelector->setValues(d->selColor.hue(), d->selColor.saturation());
-        d->VSelector->setValue(d->selColor.value());
-
-        // set colors
-        d->HSSelector->blockSignals(true);
-        d->HSSelector->setHue(d->selColor.hue());
-        d->HSSelector->setSaturation(d->selColor.saturation());
-        d->HSSelector->setColorValue(d->selColor.value());
-        d->HSSelector->updateContents();
-        d->HSSelector->blockSignals(false);
-        d->HSSelector->repaint();
-
-        d->VSelector->blockSignals(true);
-        d->VSelector->setHue(d->selColor.hue());
-        d->VSelector->setSaturation(d->selColor.saturation());
-        d->VSelector->setColorValue(d->selColor.value());
-        d->VSelector->updateContents();
-        d->VSelector->blockSignals(false);
-        d->VSelector->repaint();
-
-        slotTimer();
-    }
-}
-
-void RedEyeTool::slotColorSelectedFromTarget(const DColor& color)
-{
-    d->gboxSettings->histogramBox()->histogram()->setHistogramGuideByColor(color);
-}
-
 void RedEyeTool::readSettings()
 {
     KSharedConfig::Ptr config = KSharedConfig::openConfig();
     KConfigGroup group        = config->group(d->configGroupName);
 
-    d->gboxSettings->histogramBox()->setChannel((ChannelType)group.readEntry(d->configHistogramChannelEntry,
                
-            (int)LuminosityChannel));
-    d->gboxSettings->histogramBox()->setScale((HistogramScale)group.readEntry(d->configHistogramScaleEntry,
                
-            (int)LogScaleHistogram));
-
-    d->redThreshold->setValue(group.readEntry(d->configRedThresholdEntry,       \
                d->redThreshold->defaultValue()));
-    d->smoothLevel->setValue(group.readEntry(d->configSmoothLevelEntry,         \
                d->smoothLevel->defaultValue()));
-    d->HSSelector->setHue(group.readEntry(d->configHueColoringTintEntry,        0));
-    d->HSSelector->setSaturation(group.readEntry(d->configSatColoringTintEntry, \
                128));
-    d->VSelector->setValue(group.readEntry(d->configValColoringTintEntry,       \
                255));
-    d->tintLevel->setValue(group.readEntry(d->configTintLevelEntry,             \
                d->tintLevel->defaultValue()));
-
-    QColor col;
-    col.setHsv(d->HSSelector->hue(),
-               d->HSSelector->saturation(),
-               d->VSelector->value());
-    setColor(col);
+    d->gboxSettings->histogramBox()->setChannel((ChannelType)group.readEntry(d->configHistogramChannelEntry, \
(int)LuminosityChannel)); +    \
d->gboxSettings->histogramBox()->setScale((HistogramScale)group.readEntry(d->configHistogramScaleEntry, \
(int)LogScaleHistogram)); +    d->settingsView->readSettings(group);
 }
 
 void RedEyeTool::writeSettings()
 {
     KSharedConfig::Ptr config = KSharedConfig::openConfig();
     KConfigGroup group        = config->group(d->configGroupName);
+
     group.writeEntry(d->configHistogramChannelEntry, \
                (int)d->gboxSettings->histogramBox()->channel());
     group.writeEntry(d->configHistogramScaleEntry,   \
                (int)d->gboxSettings->histogramBox()->scale());
-    group.writeEntry(d->configRedThresholdEntry,     d->redThreshold->value());
-    group.writeEntry(d->configSmoothLevelEntry,      d->smoothLevel->value());
-    group.writeEntry(d->configHueColoringTintEntry,  d->HSSelector->hue());
-    group.writeEntry(d->configSatColoringTintEntry,  d->HSSelector->saturation());
-    group.writeEntry(d->configValColoringTintEntry,  d->VSelector->value());
-    group.writeEntry(d->configTintLevelEntry,        d->tintLevel->value());
+    d->settingsView->writeSettings(group);
 
     config->sync();
 }
 
 void RedEyeTool::slotResetSettings()
 {
-    d->redThreshold->blockSignals(true);
-    d->HSSelector->blockSignals(true);
-    d->VSelector->blockSignals(true);
-    d->tintLevel->blockSignals(true);
-
-    d->redThreshold->slotReset();
-    d->smoothLevel->slotReset();
-    d->tintLevel->slotReset();
-
-    // Black color by default
-    QColor col;
-    col.setHsv(0, 0, 0);
-    setColor(col);
-
-    d->redThreshold->blockSignals(false);
-    d->HSSelector->blockSignals(false);
-    d->VSelector->blockSignals(false);
-    d->tintLevel->blockSignals(false);
-
+    d->settingsView->resetToDefault();
     slotPreview();
 }
 
-void RedEyeTool::slotPreview()
+void RedEyeTool::preparePreview()
 {
-    qApp->setOverrideCursor( Qt::WaitCursor );
+    RedEyeCorrectionContainer settings = d->settingsView->settings();
 
     d->gboxSettings->histogramBox()->histogram()->stopHistogramComputation();
 
-    // Here, we need to use the real selection image data because we will apply
-    // a Gaussian blur filter on pixels and we cannot use directly the preview \
                scaled image
-    // else the blur radius will not give the same result between preview and final \
                rendering.
-    ImageIface* const iface = d->previewWidget->imageIface();
-    DImg selection          = iface->selection();
-
-    redEyeFilter(selection);
-
-    DImg preview = selection.smoothScale(iface->previewSize());
+    DImg original = d->previewWidget->getOriginalImage();
+    setFilter(new RedEyeCorrectionFilter(&original, this, settings));
+}
 
-    iface->setPreview(preview);
-    d->previewWidget->updatePreview();
+void RedEyeTool::setPreviewImage()
+{
+    DImg preview = filter()->getTargetImage().copy(d->previewWidget->getOriginalImageRegionToRender());
 +    d->previewWidget->setPreviewImage(preview);
 
     // Update histogram.
 
-    d->gboxSettings->histogramBox()->histogram()->updateData(selection.copy(), \
                DImg(), false);
-
-    qApp->restoreOverrideCursor();
+    d->gboxSettings->histogramBox()->histogram()->updateData(preview.copy(), DImg(), \
false);  }
 
-void RedEyeTool::finalRendering()
+void RedEyeTool::prepareFinal()
 {
-    qApp->setOverrideCursor( Qt::WaitCursor );
-
-    ImageIface* const iface = d->previewWidget->imageIface();
-    DImg selection          = iface->selection();
-
-    redEyeFilter(selection);
-
-    FilterAction action(QLatin1String("digikam:redEyeFilter"), 1);
-    action.setDisplayableName(i18n("Red Eye Filter"));
+    RedEyeCorrectionContainer settings = d->settingsView->settings();
 
-    iface->setSelection(i18n("Red Eyes Correction"), action, selection);
+    ImageIface iface;
 
-    qApp->restoreOverrideCursor();
+    setFilter(new RedEyeCorrectionFilter(iface.original(), this, settings));
 }
 
-void RedEyeTool::redEyeFilter(DImg& selection)
+void RedEyeTool::setFinalImage()
 {
-    // To restore selection alpha properties at end.
-    bool selHasAlpha = selection.hasAlpha();
-
-    DImg mask(selection.width(), selection.height(), selection.sixteenBit(), true,
-              selection.bits(), true);
-
-    selection          = mask.copy();
-    float redThreshold = d->redThreshold->value()/10.0f;
-    int hue            = d->VSelector->hue();
-    int sat            = d->VSelector->saturation();
-    int val            = d->VSelector->value();
-    QColor coloring    = QColor::fromHsv(hue, sat, val);
-
-    struct channel
-    {
-        float red_gain;
-        float green_gain;
-        float blue_gain;
-    };
-
-    channel red_chan, green_chan, blue_chan;
-
-    red_chan.red_gain     = 0.1f;
-    red_chan.green_gain   = 0.6f;
-    red_chan.blue_gain    = 0.3f;
-
-    green_chan.red_gain   = 0.0f;
-    green_chan.green_gain = 1.0f;
-    green_chan.blue_gain  = 0.0f;
-
-    blue_chan.red_gain    = 0.0f;
-    blue_chan.green_gain  = 0.0f;
-    blue_chan.blue_gain   = 1.0f;
-
-    float red_norm, green_norm, blue_norm;
-    int  level = 201 - d->tintLevel->value();
-
-    red_norm   = 1.0f / (red_chan.red_gain   + red_chan.green_gain   + \
                red_chan.blue_gain);
-    green_norm = 1.0f / (green_chan.red_gain + green_chan.green_gain + \
                green_chan.blue_gain);
-    blue_norm  = 1.0f / (blue_chan.red_gain  + blue_chan.green_gain  + \
                blue_chan.blue_gain);
-
-    red_norm   *= coloring.red()   / level;
-    green_norm *= coloring.green() / level;
-    blue_norm  *= coloring.blue()  / level;
-
-    // Perform a red color pixels detection in selection image and create a \
                correction mask using an alpha channel.
-
-    if (!selection.sixteenBit())         // 8 bits image.
-    {
-        uchar* ptr  = selection.bits();
-        uchar* mptr = mask.bits();
-        uchar  r, g, b, r1, g1, b1;
-
-        for (uint i = 0 ; i < selection.width() * selection.height() ; ++i)
-        {
-            b       = ptr[0];
-            g       = ptr[1];
-            r       = ptr[2];
-            mptr[3] = 255;
-
-            if (r >= ( redThreshold * g))
-            {
-                r1 = qMin(255, (int)(red_norm   * (red_chan.red_gain     * r +
-                                                   red_chan.green_gain   * g +
-                                                   red_chan.blue_gain    * b)));
-
-                g1 = qMin(255, (int)(green_norm * (green_chan.red_gain   * r +
-                                                   green_chan.green_gain * g +
-                                                   green_chan.blue_gain  * b)));
-
-                b1 = qMin(255, (int)(blue_norm  * (blue_chan.red_gain    * r +
-                                                   blue_chan.green_gain  * g +
-                                                   blue_chan.blue_gain   * b)));
-
-                mptr[0] = b1;
-                mptr[1] = g1;
-                mptr[2] = r1;
-                mptr[3] = qMin( (int)((r-g) / 150.0 * 255.0), 255);
-            }
-
-            ptr += 4;
-            mptr+= 4;
-        }
-    }
-    else                                 // 16 bits image.
-    {
-        unsigned short* ptr  = reinterpret_cast<unsigned short*>(selection.bits());
-        unsigned short* mptr = reinterpret_cast<unsigned short*>(mask.bits());
-        unsigned short  r, g, b, r1, g1, b1;
-
-        for (uint i = 0 ; i < selection.width() * selection.height() ; ++i)
-        {
-            b       = ptr[0];
-            g       = ptr[1];
-            r       = ptr[2];
-            mptr[3] = 65535;
-
-            if (r >= ( redThreshold * g))
-            {
-                r1 = qMin(65535, (int)(red_norm   * (red_chan.red_gain     * r +
-                                                     red_chan.green_gain   * g +
-                                                     red_chan.blue_gain    * b)));
-
-                g1 = qMin(65535, (int)(green_norm * (green_chan.red_gain   * r +
-                                                     green_chan.green_gain * g +
-                                                     green_chan.blue_gain  * b)));
-
-                b1 = qMin(65535, (int)(blue_norm  * (blue_chan.red_gain    * r +
-                                                     blue_chan.green_gain  * g +
-                                                     blue_chan.blue_gain   * b)));
-
-                mptr[0] = b1;
-                mptr[1] = g1;
-                mptr[2] = r1;
-                mptr[3] = qMin( (int)((r-g) / 38400.0 * 65535.0), 65535);
-            }
-
-            ptr += 4;
-            mptr+= 4;
-        }
-    }
-
-    // Now, we will blur only the transparency pixels from the mask.
-
-    DImg mask2 = mask.copy();
-    BlurFilter blur(&mask2, 0L, d->smoothLevel->value());
-    blur.startFilterDirectly();
-    mask2.putImageData(blur.getTargetImage().bits());
-
-    if (!selection.sixteenBit())         // 8 bits image.
-    {
-        uchar* mptr  = mask.bits();
-        uchar* mptr2 = mask2.bits();
-
-        for (uint i = 0 ; i < mask2.width() * mask2.height() ; ++i)
-        {
-            if (mptr2[3] < 255)
-            {
-                mptr[0] = mptr2[0];
-                mptr[1] = mptr2[1];
-                mptr[2] = mptr2[2];
-                mptr[3] = mptr2[3];
-            }
-
-            mptr += 4;
-            mptr2+= 4;
-        }
-    }
-    else                                // 16 bits image.
-    {
-        unsigned short* mptr  = reinterpret_cast<unsigned short*>(mask.bits());
-        unsigned short* mptr2 = reinterpret_cast<unsigned short*>(mask2.bits());
-
-        for (uint i = 0 ; i < mask2.width() * mask2.height() ; ++i)
-        {
-            if (mptr2[3] < 65535)
-            {
-                mptr[0] = mptr2[0];
-                mptr[1] = mptr2[1];
-                mptr[2] = mptr2[2];
-                mptr[3] = mptr2[3];
-            }
-
-            mptr += 4;
-            mptr2+= 4;
-        }
-    }
-
-    // - Perform pixels blending using alpha channel between the mask and the \
                selection.
-
-    DColorComposer* const composer = \
                DColorComposer::getComposer(DColorComposer::PorterDuffSrcOver);
-
-    // NOTE: 'mask' is the Source image, 'selection' is the Destination image.
-
-    selection.bitBlendImage(composer, &mask,
-                            0, 0, mask.width(), mask.height(),
-                            0, 0);
-
-    delete composer;
-
-    if (!selHasAlpha)
-        selection.removeAlphaChannel();
+    ImageIface iface;
+    iface.setOriginal(i18n("Red Eyes Correction"), filter()->filterAction(), \
filter()->getTargetImage());  }
 
 }  // namespace Digikam
diff --git a/utilities/imageeditor/tools/enhance/redeyetool.h \
b/utilities/imageeditor/tools/enhance/redeyetool.h index 2a937db..fd2737b 100644
--- a/utilities/imageeditor/tools/enhance/redeyetool.h
+++ b/utilities/imageeditor/tools/enhance/redeyetool.h
@@ -37,7 +37,7 @@ namespace Digikam
 class DImg;
 class DColor;
 
-class RedEyeTool : public EditorTool
+class RedEyeTool : public EditorToolThreaded
 {
     Q_OBJECT
 
@@ -48,19 +48,16 @@ public:
 
 private Q_SLOTS:
 
-    void slotPreview();
     void slotResetSettings();
-    void slotColorSelectedFromTarget(const DColor& color);
-    void slotHSChanged(int h, int s);
-    void slotVChanged(int v);
 
 private:
 
     void readSettings();
     void writeSettings();
-    void finalRendering();
-    void redEyeFilter(DImg& selection);
-    void setColor(const QColor& color);
+    void preparePreview();
+    void prepareFinal();
+    void setPreviewImage();
+    void setFinalImage();
 
 private:
 
diff --git a/utilities/imageeditor/widgets/imageregionwidget.cpp \
b/utilities/imageeditor/widgets/imageregionwidget.cpp index c3a5612..4453605 100644
--- a/utilities/imageeditor/widgets/imageregionwidget.cpp
+++ b/utilities/imageeditor/widgets/imageregionwidget.cpp
@@ -178,6 +178,11 @@ void ImageRegionWidget::setPreviewImage(const DImg& img)
     d_ptr->item->setTargetImage(image);
 }
 
+DImg ImageRegionWidget::getOriginalImage() const
+{
+    return (d_ptr->item->image().copy());
+}
+
 DImg ImageRegionWidget::getOriginalRegionImage(bool useDownscaledImage) const
 {
     DImg image = d_ptr->item->image().copy(getOriginalImageRegionToRender());
diff --git a/utilities/imageeditor/widgets/imageregionwidget.h \
b/utilities/imageeditor/widgets/imageregionwidget.h index 2f83dcf..1db0ff9 100644
--- a/utilities/imageeditor/widgets/imageregionwidget.h
+++ b/utilities/imageeditor/widgets/imageregionwidget.h
@@ -67,6 +67,8 @@ public:
      */
     DImg   getOriginalRegionImage(bool useDownscaledImage = false) const;
 
+    DImg   getOriginalImage() const;
+
     void   setPreviewImage(const DImg& img);
 
     void   setCapturePointMode(bool b);


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic