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

0001 /* ============================================================
0002  *
0003  * Date        : 2008-02-10
0004  * Description : a tool to fix automatically camera lens aberrations
0005  *
0006  * SPDX-FileCopyrightText: 2008      by Adrian Schroeter <adrian at suse dot de>
0007  * SPDX-FileCopyrightText: 2008-2024 by Gilles Caulier <caulier dot gilles at gmail dot com>
0008  *
0009  * SPDX-License-Identifier: GPL-2.0-or-later
0010  *
0011  * ============================================================ */
0012 
0013 #include "lensautofixtool.h"
0014 
0015 // Qt includes
0016 
0017 #include <QBitmap>
0018 #include <QBrush>
0019 #include <QCheckBox>
0020 #include <QGridLayout>
0021 #include <QLabel>
0022 #include <QPainter>
0023 #include <QPen>
0024 #include <QPixmap>
0025 #include <QTimer>
0026 #include <QIcon>
0027 
0028 // KDE includes
0029 
0030 #include <klocalizedstring.h>
0031 #include <ksharedconfig.h>
0032 #include <kconfiggroup.h>
0033 
0034 // Local includes
0035 
0036 #include "dmetadata.h"
0037 #include "editortoolsettings.h"
0038 #include "imageiface.h"
0039 #include "imageguidewidget.h"
0040 #include "lensfuniface.h"
0041 #include "lensfunfilter.h"
0042 #include "lensfunsettings.h"
0043 #include "lensfuncameraselector.h"
0044 #include "dexpanderbox.h"
0045 
0046 namespace DigikamEditorLensAutoFixToolPlugin
0047 {
0048 
0049 class Q_DECL_HIDDEN LensAutoFixTool::Private
0050 {
0051 public:
0052 
0053     explicit Private()
0054       : configGroupName (QLatin1String("Lens Auto-Correction Tool")),
0055         configShowGrid  (QLatin1String("Show Grid")),
0056         maskPreviewLabel(nullptr),
0057         showGrid        (nullptr),
0058         settingsView    (nullptr),
0059         cameraSelector  (nullptr),
0060         previewWidget   (nullptr),
0061         gboxSettings    (nullptr)
0062     {
0063     }
0064 
0065     const QString          configGroupName;
0066     const QString          configShowGrid;
0067 
0068     QLabel*                maskPreviewLabel;
0069 
0070     QCheckBox*             showGrid;
0071 
0072     LensFunSettings*       settingsView;
0073     LensFunCameraSelector* cameraSelector;
0074 
0075     ImageGuideWidget*      previewWidget;
0076     EditorToolSettings*    gboxSettings;
0077 };
0078 
0079 LensAutoFixTool::LensAutoFixTool(QObject* const parent)
0080     : EditorToolThreaded(parent),
0081       d                 (new Private)
0082 {
0083     setObjectName(QLatin1String("lensautocorrection"));
0084     setToolName(i18n("Lens Auto-Correction"));
0085     setToolIcon(QIcon::fromTheme(QLatin1String("lensautofix")));
0086 
0087     d->previewWidget = new ImageGuideWidget(nullptr, true, ImageGuideWidget::HVGuideMode);
0088     setToolView(d->previewWidget);
0089     setPreviewModeMask(PreviewToolBar::AllPreviewModes);
0090 
0091     // -------------------------------------------------------------
0092 
0093     d->gboxSettings         = new EditorToolSettings(nullptr);
0094     QGridLayout* const grid = new QGridLayout(d->gboxSettings->plainPage());
0095 
0096     d->showGrid             = new QCheckBox(i18n("Show grid"), d->gboxSettings->plainPage());
0097     d->showGrid->setWhatsThis(i18n("Set this option to visualize the correction grid to be applied."));
0098 
0099     // -------------------------------------------------------------
0100 
0101     d->cameraSelector      = new LensFunCameraSelector(d->gboxSettings->plainPage());
0102     DImg* const img        = d->previewWidget->imageIface()->original();
0103     d->cameraSelector->setMetadata(img->getMetadata());
0104     DLineWidget* const line = new DLineWidget(Qt::Horizontal, d->gboxSettings->plainPage());
0105 
0106     // -------------------------------------------------------------
0107 
0108     d->settingsView   = new LensFunSettings(d->gboxSettings->plainPage());
0109 
0110     // -------------------------------------------------------------
0111 
0112     const int spacing = d->gboxSettings->spacingHint();
0113 
0114     grid->addWidget(d->showGrid,       0, 0, 1, 2);
0115     grid->addWidget(d->cameraSelector, 1, 0, 1, 2);
0116     grid->addWidget(line,              2, 0, 1, 2);
0117     grid->addWidget(d->settingsView,   3, 0, 1, 2);
0118     grid->setRowStretch(4, 10);
0119     grid->setContentsMargins(spacing, spacing, spacing, spacing);
0120     grid->setSpacing(spacing);
0121 
0122     setToolSettings(d->gboxSettings);
0123 
0124     // -------------------------------------------------------------
0125 
0126     connect(d->settingsView, SIGNAL(signalSettingsChanged()),
0127             this, SLOT(slotTimer()));
0128 
0129     connect(d->cameraSelector, SIGNAL(signalLensSettingsChanged()),
0130             this, SLOT(slotLensChanged()));
0131 
0132     connect(d->showGrid, SIGNAL(toggled(bool)),
0133             this, SLOT(slotTimer()));
0134 }
0135 
0136 LensAutoFixTool::~LensAutoFixTool()
0137 {
0138     delete d;
0139 }
0140 
0141 void LensAutoFixTool::slotLensChanged()
0142 {
0143     d->settingsView->setEnabledCCA(d->cameraSelector->iface()->supportsCCA());
0144     d->settingsView->setEnabledVig(d->cameraSelector->iface()->supportsVig());
0145     d->settingsView->setEnabledDist(d->cameraSelector->iface()->supportsDistortion());
0146     d->settingsView->setEnabledGeom(d->cameraSelector->iface()->supportsDistortion());
0147     slotTimer();
0148 }
0149 
0150 void LensAutoFixTool::readSettings()
0151 {
0152     d->gboxSettings->blockSignals(true);
0153     KSharedConfig::Ptr config = KSharedConfig::openConfig();
0154     KConfigGroup group        = config->group(d->configGroupName);
0155 
0156     d->showGrid->setChecked(group.readEntry(d->configShowGrid, false));
0157     d->cameraSelector->readSettings(group);
0158     d->settingsView->readSettings(group);
0159     d->gboxSettings->blockSignals(false);
0160     slotTimer();
0161 }
0162 
0163 void LensAutoFixTool::writeSettings()
0164 {
0165     KSharedConfig::Ptr config = KSharedConfig::openConfig();
0166     KConfigGroup group        = config->group(d->configGroupName);
0167 
0168     group.writeEntry(d->configShowGrid, d->showGrid->isChecked());
0169     d->cameraSelector->writeSettings(group);
0170     d->settingsView->writeSettings(group);
0171     group.sync();
0172 }
0173 
0174 void LensAutoFixTool::slotResetSettings()
0175 {
0176     d->gboxSettings->blockSignals(true);
0177     d->showGrid->setChecked(false);
0178     d->cameraSelector->resetToDefault();
0179     d->gboxSettings->blockSignals(false);
0180 }
0181 
0182 void LensAutoFixTool::preparePreview()
0183 {
0184     // Settings information must be get before to disable settings view.
0185     LensFunContainer settings = d->cameraSelector->settings();
0186     d->settingsView->assignFilterSettings(settings);
0187     ImageIface* const iface   = d->previewWidget->imageIface();
0188     DImg preview              = iface->preview();
0189 
0190     if (d->showGrid->isChecked())
0191     {
0192         QBitmap pattern(9, 9);
0193         pattern.clear();
0194         QPainter p1(&pattern);
0195         p1.setPen(QPen(Qt::black, 1));
0196         p1.drawLine(5, 0, 5, 9);
0197         p1.drawLine(0, 5, 9, 5);
0198         p1.end();
0199 
0200         QPixmap pix(preview.size());
0201         pix.fill(Qt::transparent);
0202         QPainter p2(&pix);
0203         p2.setPen(QPen(Qt::gray, 1));
0204         p2.fillRect(0, 0, pix.width(), pix.height(), QBrush(pattern));
0205         p2.end();
0206         DImg grid(pix.toImage());
0207 
0208         DColorComposer* const composer            = DColorComposer::getComposer(DColorComposer::PorterDuffNone);
0209         DColorComposer::MultiplicationFlags flags = DColorComposer::NoMultiplication;
0210 
0211         // Do alpha blending of template on dest image
0212         preview.bitBlendImage(composer, &grid, 0, 0, preview.width(), preview.height(), 0, 0, flags);
0213 
0214         delete composer;
0215     }
0216 
0217     setFilter(new LensFunFilter(&preview, this, settings));
0218 }
0219 
0220 void LensAutoFixTool::prepareFinal()
0221 {
0222     // Settings information must be handle before to disable settings view.
0223     LensFunContainer settings = d->cameraSelector->settings();
0224     d->settingsView->assignFilterSettings(settings);
0225     ImageIface iface;
0226     setFilter(new LensFunFilter(iface.original(), this, settings));
0227 }
0228 
0229 void LensAutoFixTool::setPreviewImage()
0230 {
0231     d->previewWidget->imageIface()->setPreview(filter()->getTargetImage());
0232     d->previewWidget->updatePreview();
0233 }
0234 
0235 void LensAutoFixTool::setFinalImage()
0236 {
0237     ImageIface iface;
0238     iface.setOriginal(i18n("Lens Auto-Correction"), filter()->filterAction(), filter()->getTargetImage());
0239 
0240     MetaEngineData data  = iface.originalMetadata();
0241 
0242     // Note: there are certain situations in the editor where these metadata changes may be undone.
0243     // Ignore for now, as they are not critical.
0244     LensFunFilter* const fltr = dynamic_cast<LensFunFilter*>(filter());
0245 
0246     if (fltr)
0247     {
0248         fltr->registerSettingsToXmp(data);
0249     }
0250 
0251     iface.setOriginalMetadata(data);
0252 }
0253 
0254 } // namespace DigikamEditorLensAutoFixToolPlugin
0255 
0256 #include "moc_lensautofixtool.cpp"