File indexing completed on 2025-01-19 03:50:58

0001 /* ============================================================
0002  *
0003  * This file is a part of digiKam project
0004  * https://www.digikam.org
0005  *
0006  * Date        : 2012-12-28
0007  * Description : crop image batch tool.
0008  *
0009  * SPDX-FileCopyrightText: 2012-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 "crop.h"
0016 
0017 // Qt includes
0018 
0019 #include <QLabel>
0020 #include <QRect>
0021 #include <QWidget>
0022 #include <QGridLayout>
0023 #include <QCheckBox>
0024 #include <QApplication>
0025 #include <QStyle>
0026 
0027 // KDE includes
0028 
0029 #include <klocalizedstring.h>
0030 
0031 // Local includes
0032 
0033 #include "dnuminput.h"
0034 #include "autocrop.h"
0035 #include "dimg.h"
0036 #include "dimgbuiltinfilter.h"
0037 
0038 namespace DigikamBqmCropPlugin
0039 {
0040 
0041 class Q_DECL_HIDDEN Crop::Private
0042 {
0043 public:
0044 
0045     explicit Private()
0046       : autoCrop      (nullptr),
0047         heightInput   (nullptr),
0048         widthInput    (nullptr),
0049         xInput        (nullptr),
0050         yInput        (nullptr),
0051         changeSettings(true)
0052     {
0053     }
0054 
0055 public:
0056 
0057     QCheckBox*    autoCrop;
0058 
0059     DIntNumInput* heightInput;
0060     DIntNumInput* widthInput;
0061     DIntNumInput* xInput;
0062     DIntNumInput* yInput;
0063 
0064     bool          changeSettings;
0065 };
0066 
0067 Crop::Crop(QObject* const parent)
0068     : BatchTool(QLatin1String("Crop"), TransformTool, parent),
0069       d        (new Private)
0070 {
0071 }
0072 
0073 Crop::~Crop()
0074 {
0075     delete d;
0076 }
0077 
0078 BatchTool* Crop::clone(QObject* const parent) const
0079 {
0080     return new Crop(parent);
0081 }
0082 
0083 void Crop::registerSettingsWidget()
0084 {
0085     m_settingsWidget  = new QWidget;
0086 
0087     const int spacing = qMin(QApplication::style()->pixelMetric(QStyle::PM_LayoutHorizontalSpacing),
0088                              QApplication::style()->pixelMetric(QStyle::PM_LayoutVerticalSpacing));
0089 
0090     // -------------------------------------------------------------
0091 
0092     d->autoCrop = new QCheckBox(i18n("Auto-Crop"), m_settingsWidget);
0093     d->autoCrop->setWhatsThis(i18n("Compute automatically crop area settings by a parse of "
0094                                    "black hole image borders."));
0095 
0096     QLabel* const positionLabel = new QLabel(i18n("Position:"), m_settingsWidget);
0097     positionLabel->setAlignment(Qt::AlignLeft|Qt::AlignVCenter);
0098 
0099     d->xInput = new DIntNumInput(m_settingsWidget);
0100     d->xInput->setWhatsThis( i18n("Set here the top left selection corner position for cropping."));
0101     d->xInput->setRange(0, 99999, 1);
0102     d->xInput->setDefaultValue(50);
0103 
0104     d->yInput = new DIntNumInput(m_settingsWidget);
0105     d->yInput->setWhatsThis( i18n("Set here the top left selection corner position for cropping."));
0106     d->yInput->setRange(0, 99999, 1);
0107     d->yInput->setDefaultValue(50);
0108 
0109     // -------------------------------------------------------------
0110 
0111     QLabel* const sizeLabel = new QLabel(i18n("Size:"), m_settingsWidget);
0112     sizeLabel->setAlignment(Qt::AlignLeft|Qt::AlignVCenter);
0113 
0114     d->widthInput = new DIntNumInput(m_settingsWidget);
0115     d->widthInput->setWhatsThis( i18n("Set here the width selection for cropping."));
0116     d->widthInput->setRange(0, 99999, 1);
0117     d->widthInput->setDefaultValue(800);
0118 
0119     d->heightInput = new DIntNumInput(m_settingsWidget);
0120     d->heightInput->setWhatsThis( i18n("Set here the height selection for cropping."));
0121     d->heightInput->setRange(0, 99999, 1);
0122     d->heightInput->setDefaultValue(600);
0123 
0124     // -------------------------------------------------------------
0125 
0126     QGridLayout* const mainLayout = new QGridLayout(m_settingsWidget);
0127     mainLayout->addWidget(d->autoCrop,                  0, 0, 1, 1);
0128     mainLayout->addWidget(positionLabel,                1, 0, 1, 1);
0129     mainLayout->addWidget(d->xInput,                    1, 1, 1, 3);
0130     mainLayout->addWidget(d->yInput,                    2, 1, 1, 3);
0131     mainLayout->addWidget(sizeLabel,                    3, 0, 1, 1);
0132     mainLayout->addWidget(d->widthInput,                3, 1, 1, 3);
0133     mainLayout->addWidget(d->heightInput,               4, 1, 1, 3);
0134     mainLayout->addWidget(new QLabel(m_settingsWidget), 5, 1, 1, 3);
0135     mainLayout->setRowStretch(5, 10);
0136     mainLayout->setContentsMargins(spacing, spacing, spacing, spacing);
0137     mainLayout->setSpacing(spacing);
0138 
0139     // -------------------------------------------------------------
0140 
0141     connect(d->autoCrop, SIGNAL(clicked(bool)),
0142             this, SLOT(slotDisableParameters(bool)));
0143 
0144     connect(this, SIGNAL(signalAutoCrop()),
0145             this, SLOT(slotSettingsChanged()));
0146 
0147     connect(d->xInput, SIGNAL(valueChanged(int)),
0148             this, SLOT(slotSettingsChanged()));
0149 
0150     connect(d->yInput, SIGNAL(valueChanged(int)),
0151             this, SLOT(slotSettingsChanged()));
0152 
0153     connect(d->widthInput, SIGNAL(valueChanged(int)),
0154             this, SLOT(slotSettingsChanged()));
0155 
0156     connect(d->heightInput, SIGNAL(valueChanged(int)),
0157             this, SLOT(slotSettingsChanged()));;
0158 
0159     BatchTool::registerSettingsWidget();
0160 }
0161 
0162 void Crop::slotDisableParameters(bool b)
0163 {
0164     d->xInput->setDisabled(b);
0165     d->yInput->setDisabled(b);
0166     d->widthInput->setDisabled(b);
0167     d->heightInput->setDisabled(b);
0168 
0169     if (b)
0170     {
0171         Q_EMIT signalAutoCrop();
0172     }
0173 }
0174 
0175 BatchToolSettings Crop::defaultSettings()
0176 {
0177     BatchToolSettings settings;
0178     settings.insert(QLatin1String("xInput"),      50);
0179     settings.insert(QLatin1String("yInput"),      50);
0180     settings.insert(QLatin1String("widthInput"),  800);
0181     settings.insert(QLatin1String("heightInput"), 600);
0182     settings.insert(QLatin1String("AutoCrop"),    false);
0183 
0184     return settings;
0185 }
0186 
0187 void Crop::slotAssignSettings2Widget()
0188 {
0189     d->changeSettings = false;
0190     d->xInput->setValue(settings()[QLatin1String("xInput")].toInt());
0191     d->yInput->setValue(settings()[QLatin1String("yInput")].toInt());
0192     d->widthInput->setValue(settings()[QLatin1String("widthInput")].toInt());
0193     d->heightInput->setValue(settings()[QLatin1String("heightInput")].toInt());
0194     d->autoCrop->setChecked(settings()[QLatin1String("AutoCrop")].toBool());
0195     d->changeSettings = true;
0196 }
0197 
0198 void Crop::slotSettingsChanged()
0199 {
0200     if (d->changeSettings)
0201     {
0202         BatchToolSettings settings;
0203         settings.insert(QLatin1String("xInput"),      d->xInput->value());
0204         settings.insert(QLatin1String("yInput"),      d->yInput->value());
0205         settings.insert(QLatin1String("widthInput"),  d->widthInput->value());
0206         settings.insert(QLatin1String("heightInput"), d->heightInput->value());
0207         settings.insert(QLatin1String("AutoCrop"),    d->autoCrop->isChecked());
0208         BatchTool::slotSettingsChanged(settings);
0209     }
0210 }
0211 
0212 bool Crop::toolOperations()
0213 {
0214     int xInput      = settings()[QLatin1String("xInput")].toInt();
0215     int yInput      = settings()[QLatin1String("yInput")].toInt();
0216     int widthInput  = settings()[QLatin1String("widthInput")].toInt();
0217     int heightInput = settings()[QLatin1String("heightInput")].toInt();
0218     bool autoCrop   = settings()[QLatin1String("AutoCrop")].toBool();
0219 
0220     if (!loadToDImg())
0221     {
0222         return false;
0223     }
0224 
0225     QRect rect(xInput, yInput, widthInput, heightInput);
0226 
0227     if (autoCrop)
0228     {
0229         AutoCrop ac(&image());
0230         ac.startFilterDirectly();
0231         rect = ac.autoInnerCrop();
0232     }
0233 
0234     if (!rect.isValid())
0235     {
0236         return false;
0237     }
0238 
0239     DImgBuiltinFilter filter(DImgBuiltinFilter::Crop, rect);
0240     applyFilter(&filter);
0241 
0242     return (savefromDImg());
0243 }
0244 
0245 } // namespace DigikamBqmCropPlugin
0246 
0247 #include "moc_crop.cpp"