File indexing completed on 2025-01-05 03:51:29

0001 /* ============================================================
0002  *
0003  * This file is a part of digiKam project
0004  * https://www.digikam.org
0005  *
0006  * Date        : 2010-09-18
0007  * Description : lens auto-fix batch tool.
0008  *
0009  * SPDX-FileCopyrightText: 2010-2024 by Gilles Caulier <caulier dot gilles at gmail dot com>
0010  *
0011  * SPDX-License-Identifier: GPL-2.0-or-later
0012  *
0013  * ============================================================ */
0014 
0015 #include "lensautofix.h"
0016 
0017 // Qt includes
0018 
0019 #include <QLabel>
0020 #include <QGridLayout>
0021 #include <QWidget>
0022 #include <QApplication>
0023 #include <QStyle>
0024 #include <QScopedPointer>
0025 
0026 // KDE includes
0027 
0028 #include <klocalizedstring.h>
0029 
0030 // Local includes
0031 
0032 #include "dlayoutbox.h"
0033 #include "dimg.h"
0034 #include "lensfunsettings.h"
0035 #include "lensfuncameraselector.h"
0036 #include "lensfuniface.h"
0037 #include "dexpanderbox.h"
0038 
0039 namespace DigikamBqmLensAutoFixPlugin
0040 {
0041 
0042 class Q_DECL_HIDDEN LensAutoFix::Private
0043 {
0044 public:
0045 
0046     explicit Private()
0047         : settingsView  (nullptr),
0048           cameraSelector(nullptr),
0049           changeSettings(true)
0050     {
0051     }
0052 
0053     LensFunSettings*       settingsView;
0054     LensFunCameraSelector* cameraSelector;
0055 
0056     bool                   changeSettings;
0057 };
0058 
0059 LensAutoFix::LensAutoFix(QObject* const parent)
0060     : BatchTool(QLatin1String("LensAutoFix"), EnhanceTool, parent),
0061       d        (new Private)
0062 {
0063     setToolTitle(i18n("Lens Auto-Correction"));
0064     setToolDescription(i18n("Fix automatically lens distortions"));
0065     setToolIconName(QLatin1String("lensautofix"));
0066 }
0067 
0068 LensAutoFix::~LensAutoFix()
0069 {
0070     delete d;
0071 }
0072 
0073 BatchTool* LensAutoFix::clone(QObject* const parent) const
0074 {
0075     return new LensAutoFix(parent);
0076 }
0077 
0078 void LensAutoFix::registerSettingsWidget()
0079 {
0080     const int spacing  = qMin(QApplication::style()->pixelMetric(QStyle::PM_LayoutHorizontalSpacing),
0081                              QApplication::style()->pixelMetric(QStyle::PM_LayoutVerticalSpacing));
0082 
0083     m_settingsWidget   = new QWidget;
0084     QLabel* const note = new QLabel(i18n("<b>Use Metadata</b> option will parse images' information at "
0085                                          "queue run-time to find relevant lens features."));
0086     note->setWordWrap(true);
0087     note->setFrameStyle(QFrame::StyledPanel | QFrame::Raised);
0088 
0089     d->cameraSelector       = new LensFunCameraSelector();
0090     DLineWidget* const line = new DLineWidget(Qt::Horizontal);
0091     d->settingsView         = new LensFunSettings();
0092     d->cameraSelector->setPassiveMetadataUsage(true);
0093     d->cameraSelector->setEnabledUseMetadata(true);
0094 
0095     QGridLayout* const grid = new QGridLayout(m_settingsWidget);
0096     grid->addWidget(note,              0, 0, 1, 2);
0097     grid->addWidget(d->cameraSelector, 1, 0, 1, 2);
0098     grid->addWidget(line,              2, 0, 1, 2);
0099     grid->addWidget(d->settingsView,   3, 0, 1, 2);
0100     grid->setRowStretch(4, 10);
0101     grid->setContentsMargins(spacing, spacing, spacing, spacing);
0102     grid->setSpacing(spacing);
0103 
0104     connect(d->settingsView, SIGNAL(signalSettingsChanged()),
0105             this, SLOT(slotSettingsChanged()));
0106 
0107     connect(d->cameraSelector, SIGNAL(signalLensSettingsChanged()),
0108             this, SLOT(slotSettingsChanged()));
0109 
0110     BatchTool::registerSettingsWidget();
0111 }
0112 
0113 BatchToolSettings LensAutoFix::defaultSettings()
0114 {
0115     BatchToolSettings prm;
0116 
0117     prm.insert(QLatin1String("UseMetadata"),     true);
0118     prm.insert(QLatin1String("filterCCA"),       true);
0119     prm.insert(QLatin1String("filterVIG"),       true);
0120     prm.insert(QLatin1String("filterDST"),       true);
0121     prm.insert(QLatin1String("filterGEO"),       true);
0122 
0123     prm.insert(QLatin1String("cropFactor"),      -1.0);
0124     prm.insert(QLatin1String("focalLength"),     -1.0);
0125     prm.insert(QLatin1String("aperture"),        -1.0);
0126     prm.insert(QLatin1String("subjectDistance"), -1.0);
0127 
0128     prm.insert(QLatin1String("cameraMake"),      QString());
0129     prm.insert(QLatin1String("cameraModel"),     QString());
0130     prm.insert(QLatin1String("lensModel"),       QString());
0131 
0132     return prm;
0133 }
0134 
0135 void LensAutoFix::slotAssignSettings2Widget()
0136 {
0137     d->changeSettings = false;
0138 
0139     d->cameraSelector->setUseMetadata(settings()[QLatin1String("UseMetadata")].toBool());
0140     LensFunContainer lfPrm;
0141 
0142     lfPrm.filterCCA       = settings()[QLatin1String("filterCCA")].toBool();
0143     lfPrm.filterVIG       = settings()[QLatin1String("filterVIG")].toBool();
0144     lfPrm.filterDST       = settings()[QLatin1String("filterDST")].toBool();
0145     lfPrm.filterGEO       = settings()[QLatin1String("filterGEO")].toBool();
0146 
0147     lfPrm.cropFactor      = settings()[QLatin1String("cropFactor")].toDouble();
0148     lfPrm.focalLength     = settings()[QLatin1String("focalLength")].toDouble();
0149     lfPrm.aperture        = settings()[QLatin1String("aperture")].toDouble();
0150     lfPrm.subjectDistance = settings()[QLatin1String("subjectDistance")].toDouble();
0151 
0152     lfPrm.cameraMake      = settings()[QLatin1String("cameraMake")].toString();
0153     lfPrm.cameraModel     = settings()[QLatin1String("cameraModel")].toString();
0154     lfPrm.lensModel       = settings()[QLatin1String("lensModel")].toString();
0155 
0156     d->cameraSelector->setSettings(lfPrm);
0157     d->settingsView->setFilterSettings(lfPrm);
0158 
0159     // Update checkbox options about Lens corrections available.
0160     d->settingsView->setEnabledCCA(d->cameraSelector->useMetadata()  ? true : d->cameraSelector->iface()->supportsCCA());
0161     d->settingsView->setEnabledVig(d->cameraSelector->useMetadata()  ? true : d->cameraSelector->iface()->supportsVig());
0162     d->settingsView->setEnabledDist(d->cameraSelector->useMetadata() ? true : d->cameraSelector->iface()->supportsDistortion());
0163     d->settingsView->setEnabledGeom(d->cameraSelector->useMetadata() ? true : d->cameraSelector->iface()->supportsGeometry());
0164 
0165     d->changeSettings = true;
0166 }
0167 
0168 void LensAutoFix::slotSettingsChanged()
0169 {
0170     if (d->changeSettings)
0171     {
0172         BatchToolSettings prm;
0173         LensFunContainer  camSettings    = d->cameraSelector->settings();
0174         LensFunContainer  filterSettings = d->settingsView->settings();
0175 
0176         prm.insert(QLatin1String("UseMetadata"),     (bool)d->cameraSelector->useMetadata());
0177 
0178         prm.insert(QLatin1String("filterCCA"),       (bool)filterSettings.filterCCA);
0179         prm.insert(QLatin1String("filterVIG"),       (bool)filterSettings.filterVIG);
0180         prm.insert(QLatin1String("filterDST"),       (bool)filterSettings.filterDST);
0181         prm.insert(QLatin1String("filterGEO"),       (bool)filterSettings.filterGEO);
0182 
0183         prm.insert(QLatin1String("cropFactor"),      (double)camSettings.cropFactor);
0184         prm.insert(QLatin1String("focalLength"),     (double)camSettings.focalLength);
0185         prm.insert(QLatin1String("aperture"),        (double)camSettings.aperture);
0186         prm.insert(QLatin1String("subjectDistance"), (double)camSettings.subjectDistance);
0187 
0188         prm.insert(QLatin1String("cameraMake"),      camSettings.cameraMake);
0189         prm.insert(QLatin1String("cameraModel"),     camSettings.cameraModel);
0190         prm.insert(QLatin1String("lensModel"),       camSettings.lensModel);
0191 
0192         BatchTool::slotSettingsChanged(prm);
0193     }
0194 }
0195 
0196 bool LensAutoFix::toolOperations()
0197 {
0198     if (!loadToDImg())
0199     {
0200         return false;
0201     }
0202 
0203     LensFunContainer prm;
0204 
0205     bool useMeta = settings()[QLatin1String("UseMetadata")].toBool();
0206 
0207     if (useMeta)
0208     {
0209         LensFunIface iface;
0210         QScopedPointer<DMetadata> meta(new DMetadata(image().getMetadata()));
0211         LensFunIface::MetadataMatch ret = iface.findFromMetadata(meta.data());
0212         prm                             = iface.settings();
0213 
0214         if (ret != LensFunIface::MetadataExactMatch)
0215         {
0216             setErrorDescription(i18n("Cannot find all lens information to process lens auto-corrections"));
0217             return false;
0218         }
0219 
0220         prm.filterCCA       = settings()[QLatin1String("filterCCA")].toBool();
0221         prm.filterVIG       = settings()[QLatin1String("filterVIG")].toBool();
0222         prm.filterDST       = settings()[QLatin1String("filterDST")].toBool();
0223         prm.filterGEO       = settings()[QLatin1String("filterGEO")].toBool();
0224     }
0225     else
0226     {
0227         prm.filterCCA       = settings()[QLatin1String("filterCCA")].toBool();
0228         prm.filterVIG       = settings()[QLatin1String("filterVIG")].toBool();
0229         prm.filterDST       = settings()[QLatin1String("filterDST")].toBool();
0230         prm.filterGEO       = settings()[QLatin1String("filterGEO")].toBool();
0231 
0232         prm.cropFactor      = settings()[QLatin1String("cropFactor")].toDouble();
0233         prm.focalLength     = settings()[QLatin1String("focalLength")].toDouble();
0234         prm.aperture        = settings()[QLatin1String("aperture")].toDouble();
0235         prm.subjectDistance = settings()[QLatin1String("subjectDistance")].toDouble();
0236 
0237         prm.cameraMake      = settings()[QLatin1String("cameraMake")].toString();
0238         prm.cameraModel     = settings()[QLatin1String("cameraModel")].toString();
0239         prm.lensModel       = settings()[QLatin1String("lensModel")].toString();
0240     }
0241 
0242     LensFunFilter filter(&image(), nullptr, prm);
0243     applyFilter(&filter);
0244 
0245     MetaEngineData data = image().getMetadata();
0246     filter.registerSettingsToXmp(data);
0247     image().setMetadata(data);
0248 
0249     return savefromDImg();
0250 }
0251 
0252 } // namespace DigikamBqmLensAutoFixPlugin
0253 
0254 #include "moc_lensautofix.cpp"