Bug 177827

Summary: Add vignetting effect to Digikam
Product: [Applications] digikam Reporter: Jonathan <jonathan>
Component: Plugin-Editor-VignettingAssignee: Digikam Developers <digikam-bugs-null>
Status: RESOLVED FIXED    
Severity: wishlist CC: caulier.gilles, Julien, rbr28
Priority: NOR    
Version: unspecified   
Target Milestone: ---   
Platform: Fedora RPMs   
OS: Linux   
Latest Commit: Version Fixed In: 1.1.0
Sentry Crash Report:

Description Jonathan 2008-12-15 07:44:33 UTC
Version:            (using KDE 4.1.3)
Compiler:          gcc (GCC) 4.3.2 20081105 (Red Hat 4.3.2-7) 
OS:                Linux
Installed from:    Fedora RPMs

I think a great addition to Digikam would be to apply a vignetting effect to a photo that you are editing. There is currently a vignetting correction tool available.

The current vignetting correction tool works very well. From what I can tell it works by applying a white vignette (anti-vignette?) to the photo. I wonder if it would be difficult to just reverse the color to add the desired vignetting effect.
Comment 1 caulier.gilles 2009-07-09 06:17:11 UTC
*** Bug 199500 has been marked as a duplicate of this bug. ***
Comment 2 caulier.gilles 2010-01-15 19:38:45 UTC
SVN commit 1075137 by jnarboux:

Add option to add vignetting.
Fix radius slider whose range was too large.

CCBUGS: 218906 177827




 M  +23 -11    antivignetting.cpp
 M  +4 -1      antivignetting.h
 M  +54 -32    antivignettingtool.cpp


--- trunk/extragear/graphics/digikam/imageplugins/lenscorrection/vignetting/antivignetting.cpp #1075136:1075137
@@ -43,15 +43,17 @@
 {

 AntiVignetting::AntiVignetting(Digikam::DImg *orgImage, QObject *parent, double density,
-                               double power, double radius, int xshift, int yshift, bool normalize)
+                               double power, double radius, int xshift, int yshift,
+                               bool normalize, bool anti)
              : Digikam::DImgThreadedFilter(orgImage, parent, "AntiVignetting")
 {
-    m_density   = density;
-    m_power     = power;
-    m_radius    = radius;
-    m_xshift    = xshift;
-    m_yshift    = yshift;
-    m_normalize = normalize;
+    m_density        = density;
+    m_power          = power;
+    m_radius         = radius;
+    m_xshift         = xshift;
+    m_yshift         = yshift;
+    m_normalize      = normalize;
+    m_add_vignetting = anti;

    initFilter();
 }
@@ -89,7 +91,7 @@
    // of the image.

    xsize    = ((Height + 1) / 2) + abs(m_xshift);
-    ysize    = ((Width + 1)  / 2) + abs(m_yshift);
+    ysize    = ((Width  + 1) / 2) + abs(m_yshift);
    diagonal = ((int) (sqrt((xsize * xsize) + (ysize * ysize)) + 0.5)) +  1;

    ldens = new double[diagonal];
@@ -97,13 +99,23 @@
    for (i = 0 ; !m_cancel && (i < diagonal) ; ++i)
    {
        if ( i >= erad )
-           ldens[i] = 1;
+        {
+          if (!m_add_vignetting)
+            ldens[i] = 1.0;
+          else
+            ldens[i] = 0.0;
+        }
        else
-           ldens[i] =  (1.0 + (m_density - 1) * pow(1.0 - (((double) i) / (erad - 1)), m_power));
+        {
+          if (!m_add_vignetting)
+             ldens[i] =  (1.0 + (m_density - 1) * pow(1.0 - (((double) i) / (erad - 1)), m_power));
+          else
+             ldens[i] =  20.0 / (1.0 + (24 - (m_density - 1)) * pow(1.0 - (((double) i) / (erad - 1)), m_power));
+        }
    }

    xctr = ((Height + 1) / 2) + m_xshift;
-    yctr = ((Width + 1) / 2) + m_yshift;
+    yctr = ((Width  + 1) / 2) + m_yshift;

    for (row = 0 ; !m_cancel && (row < Width) ; ++row)
    {
--- trunk/extragear/graphics/digikam/imageplugins/lenscorrection/vignetting/antivignetting.h #1075136:1075137
@@ -37,7 +37,8 @@
 public:

    explicit AntiVignetting(Digikam::DImg *orgImage, QObject *parent=0, double density=2.0,
-                            double power=1.0, double radius=1.0, int xshift=0, int yshift=0, bool normalize=true);
+                            double power=1.0, double radius=1.0, int xshift=0, int yshift=0,
+                            bool normalize=true, bool anti=true);

    ~AntiVignetting(){};

@@ -55,6 +56,8 @@
    double m_density;
    double m_power;
    double m_radius;
+
+    bool   m_add_vignetting;
 };

 }  // namespace DigikamAntiVignettingImagesPlugin
--- trunk/extragear/graphics/digikam/imageplugins/lenscorrection/vignetting/antivignettingtool.cpp #1075136:1075137
@@ -27,6 +27,7 @@

 // Qt includes

+#include <QCheckBox>
 #include <QGridLayout>
 #include <QImage>
 #include <QLabel>
@@ -80,6 +81,7 @@
        configBrightnessAdjustmentEntry("BrightnessAdjustment"),
        configContrastAdjustmentEntry("ContrastAdjustment"),
        configGammaAdjustmentEntry("GammaAdjustment"),
+        configAddVignettingEntry("AddVignetting"),

        maskPreviewLabel(0),
        brightnessInput(0),
@@ -99,7 +101,8 @@
    const QString       configBrightnessAdjustmentEntry;
    const QString       configContrastAdjustmentEntry;
    const QString       configGammaAdjustmentEntry;
-
+    const QString       configAddVignettingEntry;
+
    QLabel*             maskPreviewLabel;

    RIntNumInput*       brightnessInput;
@@ -109,6 +112,8 @@
    RDoubleNumInput*    densityInput;
    RDoubleNumInput*    powerInput;
    RDoubleNumInput*    radiusInput;
+
+    QCheckBox*          addVignettingCheck;

    ImageGuideWidget*   previewWidget;
    EditorToolSettings* gboxSettings;
@@ -130,6 +135,13 @@
    d->gboxSettings = new EditorToolSettings;

    // -------------------------------------------------------------
+
+    d->addVignettingCheck = new QCheckBox(i18n("Add vignetting"));
+    d->addVignettingCheck->setWhatsThis(i18n("This option add vignetting to the image instead for removing it."
+                                               "Use it for creative effects."));
+    d->addVignettingCheck->setChecked(false);
+
+    // -------------------------------------------------------------

    d->maskPreviewLabel = new QLabel();
    d->maskPreviewLabel->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
@@ -162,7 +174,7 @@
    QLabel *label3 = new QLabel(i18n("Radius:"));
    d->radiusInput = new RDoubleNumInput();
    d->radiusInput->setDecimals(1);
-    d->radiusInput->input()->setRange(-100.0, 100.0, 0.1, true);
+    d->radiusInput->input()->setRange(0.1, 1.5, 0.1, true);
    d->radiusInput->setDefaultValue(1.0);
    d->radiusInput->setWhatsThis(i18n("This value is the radius of the center filter. It is a "
                                      "multiple of the half-diagonal measure of the image, at which "
@@ -200,21 +212,22 @@
    // -------------------------------------------------------------

    QGridLayout* mainLayout = new QGridLayout();
-    mainLayout->addWidget(d->maskPreviewLabel, 0, 0, 1, 3);
-    mainLayout->addWidget(label1,              1, 0, 1, 3);
-    mainLayout->addWidget(d->densityInput,     2, 0, 1, 3);
-    mainLayout->addWidget(label2,              3, 0, 1, 3);
-    mainLayout->addWidget(d->powerInput,       4, 0, 1, 3);
-    mainLayout->addWidget(label3,              5, 0, 1, 3);
-    mainLayout->addWidget(d->radiusInput,      6, 0, 1, 3);
-    mainLayout->addWidget(line,                7, 0, 1, 3);
-    mainLayout->addWidget(label4,              8, 0, 1, 3);
-    mainLayout->addWidget(d->brightnessInput,  9, 0, 1, 3);
-    mainLayout->addWidget(label5,             10, 0, 1, 3);
-    mainLayout->addWidget(d->contrastInput,   11, 0, 1, 3);
-    mainLayout->addWidget(label6,             12, 0, 1, 3);
-    mainLayout->addWidget(d->gammaInput,      13, 0, 1, 3);
-    mainLayout->setRowStretch(14, 10);
+    mainLayout->addWidget(d->maskPreviewLabel,    0, 0, 1, 3);
+    mainLayout->addWidget(label1,                 1, 0, 1, 3);
+    mainLayout->addWidget(d->densityInput,        2, 0, 1, 3);
+    mainLayout->addWidget(label2,                 3, 0, 1, 3);
+    mainLayout->addWidget(d->powerInput,          4, 0, 1, 3);
+    mainLayout->addWidget(label3,                 5, 0, 1, 3);
+    mainLayout->addWidget(d->radiusInput,         6, 0, 1, 3);
+    mainLayout->addWidget(line,                   7, 0, 1, 3);
+    mainLayout->addWidget(label4,                 8, 0, 1, 3);
+    mainLayout->addWidget(d->brightnessInput,     9, 0, 1, 3);
+    mainLayout->addWidget(label5,                 10, 0, 1, 3);
+    mainLayout->addWidget(d->contrastInput,       11, 0, 1, 3);
+    mainLayout->addWidget(label6,                 12, 0, 1, 3);
+    mainLayout->addWidget(d->gammaInput,          13, 0, 1, 3);
+    mainLayout->addWidget(d->addVignettingCheck,  14, 0, 1, 3);
+    mainLayout->setRowStretch(15, 10);
    mainLayout->setMargin(d->gboxSettings->spacingHint());
    mainLayout->setSpacing(d->gboxSettings->spacingHint());
    d->gboxSettings->plainPage()->setLayout(mainLayout);
@@ -242,6 +255,9 @@
            this, SLOT(slotTimer()));

    connect(d->gammaInput, SIGNAL(valueChanged (double)),
+            this, SLOT(slotTimer()));
+
+    connect(d->addVignettingCheck, SIGNAL(toggled(bool)),
            this, SLOT(slotTimer()));
 }

@@ -258,6 +274,7 @@
    d->brightnessInput->setEnabled(true);
    d->contrastInput->setEnabled(true);
    d->gammaInput->setEnabled(true);
+    d->addVignettingCheck->setEnabled(true);
 }

 void AntiVignettingTool::readSettings()
@@ -273,7 +290,7 @@
    d->brightnessInput->setValue(group.readEntry(d->configBrightnessAdjustmentEntry, d->brightnessInput->defaultValue()));
    d->contrastInput->setValue(group.readEntry(d->configContrastAdjustmentEntry,     d->contrastInput->defaultValue()));
    d->gammaInput->setValue(group.readEntry(d->configGammaAdjustmentEntry,           d->gammaInput->defaultValue()));
-
+    d->addVignettingCheck->setChecked(group.readEntry(d->configAddVignettingEntry,   false));
    blockWidgetSignals(false);

    slotEffect();
@@ -290,7 +307,8 @@
    group.writeEntry(d->configBrightnessAdjustmentEntry, d->brightnessInput->value());
    group.writeEntry(d->configContrastAdjustmentEntry,   d->contrastInput->value());
    group.writeEntry(d->configGammaAdjustmentEntry,      d->gammaInput->value());
-
+    group.writeEntry(d->configAddVignettingEntry,        d->addVignettingCheck->isChecked());
+
    group.sync();
 }

@@ -318,11 +336,13 @@
    d->brightnessInput->setEnabled(false);
    d->contrastInput->setEnabled(false);
    d->gammaInput->setEnabled(false);
+    d->addVignettingCheck->setEnabled(false);

-    double dens  = d->densityInput->value();
-    double power = d->powerInput->value();
-    double rad   = d->radiusInput->value();
-
+    double dens           = d->densityInput->value();
+    double power          = d->powerInput->value();
+    double rad            = d->radiusInput->value();
+    bool   addvignetting  = d->addVignettingCheck->isChecked();
+
    ImageIface* iface = d->previewWidget->imageIface();
    int orgWidth               = iface->originalWidth();
    int orgHeight              = iface->originalHeight();
@@ -332,7 +352,7 @@
    // Calc mask preview.
    DImg preview(ps.width(), ps.height(), false);
    memset(preview.bits(), 255, preview.numBytes());
-    AntiVignetting maskPreview(&preview, 0, dens, power, rad, 0, 0, false);
+    AntiVignetting maskPreview(&preview, 0, dens, power, rad, 0, 0, false, addvignetting);
    maskPreview.startFilterDirectly();       // Run filter without to use multithreading.
    QPixmap pix = maskPreview.getTargetImage().convertToPixmap();
    QPainter pt(&pix);
@@ -342,7 +362,7 @@
    d->maskPreviewLabel->setPixmap(pix);

    setFilter(dynamic_cast<DImgThreadedFilter *>(
-                       new AntiVignetting(iface->getOriginalImg(), this, dens, power, rad, 0, 0, true)));
+                       new AntiVignetting(iface->getOriginalImg(), this, dens, power, rad, 0, 0, true, addvignetting)));
 }

 void AntiVignettingTool::prepareFinal()
@@ -354,14 +374,15 @@
    d->contrastInput->setEnabled(false);
    d->gammaInput->setEnabled(false);

-    double dens  = d->densityInput->value();
-    double power = d->powerInput->value();
-    double rad   = d->radiusInput->value();
-
+    double dens          = d->densityInput->value();
+    double power         = d->powerInput->value();
+    double rad           = d->radiusInput->value();
+    bool   addvignetting = d->addVignettingCheck->isChecked();
+
    ImageIface iface(0, 0);

    setFilter(dynamic_cast<DImgThreadedFilter *>(
-                       new AntiVignetting(iface.getOriginalImg(), this, dens, power, rad, 0, 0, true)));
+                       new AntiVignetting(iface.getOriginalImg(), this, dens, power, rad, 0, 0, true, addvignetting)));
 }

 void AntiVignettingTool::putPreviewData()
@@ -391,7 +412,7 @@
    ImageIface* iface = d->previewWidget->imageIface();
    DImg finalImage   = filter()->getTargetImage();

-    double b = (double)(d->brightnessInput->value() / 250.0);
+    double b = (double)(d->brightnessInput->value() / 250.0);
    double c = (double)(d->contrastInput->value()   / 100.0) + (double)(1.00);
    double g = d->gammaInput->value();

@@ -412,7 +433,8 @@
    d->radiusInput->blockSignals(b);
    d->brightnessInput->blockSignals(b);
    d->contrastInput->blockSignals(b);
-    d->gammaInput->blockSignals(b);
+    d->gammaInput->blockSignals(b);
+    d->addVignettingCheck->blockSignals(b);
 }

 }  // namespace DigikamAntiVignettingImagesPlugin
Comment 3 Julien Narboux 2010-01-17 10:20:29 UTC
SVN commit 1076003 by jnarboux:

Fix bug when radius is small, polish.

CCBUG: 218906
CCBUG: 177827
FEATURE: 218906



 M  +1 -1      antivignetting.cpp  
 M  +1 -1      antivignettingtool.cpp  


WebSVN link: http://websvn.kde.org/?view=rev&revision=1076003
Comment 4 Julien Narboux 2010-01-18 08:17:43 UTC
SVN commit 1076407 by jnarboux:

Add TODO file for the vignetting tool.

CCBUG: 218906
CCBUG: 177827




 A             TODO  


WebSVN link: http://websvn.kde.org/?view=rev&revision=1076407
Comment 5 caulier.gilles 2010-01-24 20:34:26 UTC
Julien, this entry can be closed for 1.1.0 release ?

Gilles
Comment 6 Julien Narboux 2010-01-25 09:07:42 UTC
I would be nice if some people could test the new vignetting/antivignetting tool.
I close this wish.
Comment 7 caulier.gilles 2010-01-25 09:58:35 UTC
Julien,

bugzilla Visibility to users is reduced. Post an announce to users mailing list, Facebook or create a simple entry in your digiKam blog.

Gilles