diff --git a/plugins/filters/edgedetection/kis_edge_detection_filter.cpp b/plugins/filters/edgedetection/kis_edge_detection_filter.cpp index 23dc3cea3a..962bf437fb 100644 --- a/plugins/filters/edgedetection/kis_edge_detection_filter.cpp +++ b/plugins/filters/edgedetection/kis_edge_detection_filter.cpp @@ -1,168 +1,170 @@ /* * Copyright (c) 2017 Wolthera van Hövell tot Westerflier * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "kis_edge_detection_filter.h" #include "kis_wdg_edge_detection.h" #include #include #include #include #include #include #include #include #include #include #include "kis_lod_transform.h" #include #include #include K_PLUGIN_FACTORY_WITH_JSON(KritaEdgeDetectionFilterFactory, "kritaedgedetection.json", registerPlugin();) KritaEdgeDetectionFilter::KritaEdgeDetectionFilter(QObject *parent, const QVariantList &) : QObject(parent) { KisFilterRegistry::instance()->add(KisFilterSP(new KisEdgeDetectionFilter())); } KritaEdgeDetectionFilter::~KritaEdgeDetectionFilter() { } KisEdgeDetectionFilter::KisEdgeDetectionFilter(): KisFilter(id(), FiltersCategoryEdgeDetectionId, i18n("&Edge Detection...")) { setSupportsPainting(true); setSupportsAdjustmentLayers(true); setSupportsLevelOfDetail(true); setColorSpaceIndependence(FULLY_INDEPENDENT); setShowConfigurationWidget(true); } void KisEdgeDetectionFilter::processImpl(KisPaintDeviceSP device, const QRect &rect, const KisFilterConfigurationSP config, KoUpdater *progressUpdater) const { Q_ASSERT(device != 0); KisFilterConfigurationSP configuration = config ? config : new KisFilterConfiguration(id().id(), 1); KisLodTransformScalar t(device); QVariant value; configuration->getProperty("horizRadius", value); float horizontalRadius = t.scale(value.toFloat()); configuration->getProperty("vertRadius", value); float verticalRadius = t.scale(value.toFloat()); QBitArray channelFlags; if (configuration) { channelFlags = configuration->channelFlags(); } if (config->getString("type") == "canny") { KisFilterSP gaussian = KisFilterRegistry::instance()->get("gaussian blur"); KisFilterConfigurationSP gaussianConf = gaussian->defaultConfiguration(); gaussian->process(device, rect, gaussianConf, progressUpdater); int max = configuration->getInt("max_threshold", 200); int min = configuration->getInt("min_threshold", 100); KisEdgeDetectionKernel::applyCannyEdgeDetection( device, rect, horizontalRadius, verticalRadius, channelFlags, progressUpdater, max, min); return; } KisEdgeDetectionKernel::FilterType type = KisEdgeDetectionKernel::SobelVector; if (config->getString("type") == "prewitt") { type = KisEdgeDetectionKernel::Prewit; } else if (config->getString("type") == "simple") { type = KisEdgeDetectionKernel::Simple; } KisEdgeDetectionKernel::FilterOutput output = KisEdgeDetectionKernel::pythagorean; if (config->getString("output") == "xGrowth") { output = KisEdgeDetectionKernel::xGrowth; } else if (config->getString("output") == "xFall") { output = KisEdgeDetectionKernel::xFall; } else if (config->getString("output") == "yGrowth") { output = KisEdgeDetectionKernel::yGrowth; } else if (config->getString("output") == "yFall") { output = KisEdgeDetectionKernel::yFall; } else if (config->getString("output") == "radian") { output = KisEdgeDetectionKernel::radian; } KisEdgeDetectionKernel::applyEdgeDetection(device, rect, horizontalRadius, verticalRadius, type, channelFlags, progressUpdater, output, config->getBool("transparency", false)); } KisFilterConfigurationSP KisEdgeDetectionFilter::defaultConfiguration() const { KisFilterConfigurationSP config = factoryConfiguration(); config->setProperty("horizRadius", 1); config->setProperty("vertRadius", 1); config->setProperty("type", "prewitt"); config->setProperty("output", "pythagorean"); config->setProperty("lockAspect", true); config->setProperty("transparency", false); + config->setProperty("max-threshold", 200); + config->setProperty("min-threshold", 100); return config; } KisConfigWidget *KisEdgeDetectionFilter::createConfigurationWidget(QWidget *parent, const KisPaintDeviceSP dev, bool) const { Q_UNUSED(dev); return new KisWdgEdgeDetection(parent); } QRect KisEdgeDetectionFilter::neededRect(const QRect &rect, const KisFilterConfigurationSP _config, int lod) const { KisLodTransformScalar t(lod); QVariant value; /** * NOTE: integer division by two is done on purpose, * because the kernel size is always odd */ const int halfWidth = _config->getProperty("horizRadius", value) ? KisEdgeDetectionKernel::kernelSizeFromRadius(t.scale(value.toFloat())) / 2 : 5; const int halfHeight = _config->getProperty("vertRadius", value) ? KisEdgeDetectionKernel::kernelSizeFromRadius(t.scale(value.toFloat())) / 2 : 5; return rect.adjusted(-halfWidth * 2, -halfHeight * 2, halfWidth * 2, halfHeight * 2); } QRect KisEdgeDetectionFilter::changedRect(const QRect &rect, const KisFilterConfigurationSP _config, int lod) const { KisLodTransformScalar t(lod); QVariant value; const int halfWidth = _config->getProperty("horizRadius", value) ? KisEdgeDetectionKernel::kernelSizeFromRadius(t.scale(value.toFloat())) / 2 : 5; const int halfHeight = _config->getProperty("vertRadius", value) ? KisEdgeDetectionKernel::kernelSizeFromRadius(t.scale(value.toFloat())) / 2 : 5; return rect.adjusted( -halfWidth, -halfHeight, halfWidth, halfHeight); } #include "kis_edge_detection_filter.moc" diff --git a/plugins/filters/edgedetection/kis_wdg_edge_detection.cpp b/plugins/filters/edgedetection/kis_wdg_edge_detection.cpp index 3a0e14438a..0d1b63ff26 100644 --- a/plugins/filters/edgedetection/kis_wdg_edge_detection.cpp +++ b/plugins/filters/edgedetection/kis_wdg_edge_detection.cpp @@ -1,181 +1,181 @@ /* * Copyright (c) 2017 Wolthera van Hövell tot Westerflier * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "kis_wdg_edge_detection.h" #include #include #include KisWdgEdgeDetection::KisWdgEdgeDetection(QWidget* parent) : KisConfigWidget(parent) , ui(new Ui_WidgetEdgeDetection) { ui->setupUi(this); m_types << "prewitt" << "sobol" << "simple" << "canny"; m_types_translatable << i18n("Prewitt") << i18n("Sobel") << i18n("Simple") << i18n("Canny"); m_output << "pythagorean" << "xGrowth" << "xFall" << "yGrowth" << "yFall" << "radian"; m_output_translatable << i18n("All sides") << i18n("Top Edge") << i18n("Bottom Edge") << i18n("Right Edge") << i18n("Left Edge") << i18n("Direction in Radians"); ui->cmbType->addItems(m_types_translatable); ui->cmbOutput->addItems(m_output_translatable); ui->btnAspect->setKeepAspectRatio(false); ui->sldHorizontalRadius->setRange(1.0, 100.0, 2); ui->sldHorizontalRadius->setPrefix(i18n("Horizontal Radius:")); connect(ui->sldHorizontalRadius, SIGNAL(valueChanged(qreal)), this, SLOT(horizontalRadiusChanged(qreal))); ui->sldVerticalRadius->setRange(1.0, 100.0, 2); ui->sldVerticalRadius->setPrefix(i18n("Vertical Radius:")); connect(ui->sldVerticalRadius, SIGNAL(valueChanged(qreal)), this, SLOT(verticalRadiusChanged(qreal))); if (ui->cmbType->currentIndex() != 4) { ui->sldMaxThreshold->setEnabled(false); ui->sldMinThreshold->setEnabled(false); } ui->sldMaxThreshold->setRange(1, 255); ui->sldMaxThreshold->setPrefix(i18n("Max Threshold")); connect(ui->sldMaxThreshold, &KisSliderSpinBox::valueChanged, this, &KisWdgEdgeDetection::maxThresholdChanged); ui->sldMinThreshold->setRange(1, 255); ui->sldMinThreshold->setPrefix(i18n("Min Threshold:")); connect(ui->sldMinThreshold, &KisSliderSpinBox::valueChanged, this, &KisWdgEdgeDetection::minThresholdChanged); connect(ui->cmbType, QOverload::of(&QComboBox::currentIndexChanged), this, &KisWdgEdgeDetection::detectionTypeChanged); connect(ui->btnAspect, SIGNAL(keepAspectRatioChanged(bool)), this, SLOT(aspectLockChanged(bool))); connect(ui->cmbType, SIGNAL(currentIndexChanged(int)), this, SIGNAL(sigConfigurationItemChanged())); connect(ui->cmbOutput, SIGNAL(currentIndexChanged(int)), this, SIGNAL(sigConfigurationItemChanged())); connect(ui->sldHorizontalRadius, SIGNAL(valueChanged(qreal)), this, SIGNAL(sigConfigurationItemChanged())); connect(ui->sldVerticalRadius, SIGNAL(valueChanged(qreal)), this, SIGNAL(sigConfigurationItemChanged())); connect(ui->chkTransparent, SIGNAL(clicked()), this, SIGNAL(sigConfigurationItemChanged())); connect(ui->sldMinThreshold, SIGNAL(valueChanged(int)), this, SIGNAL(sigConfigurationItemChanged())); connect(ui->sldMaxThreshold, SIGNAL(valueChanged(int)), this, SIGNAL(sigConfigurationItemChanged())); } KisWdgEdgeDetection::~KisWdgEdgeDetection() { delete ui; } KisPropertiesConfigurationSP KisWdgEdgeDetection::configuration() const { KisFilterConfigurationSP config = new KisFilterConfiguration("edge detection", 1); config->setProperty("horizRadius", ui->sldHorizontalRadius->value()); config->setProperty("vertRadius", ui->sldVerticalRadius->value()); config->setProperty("type", m_types.at(ui->cmbType->currentIndex())); config->setProperty("output", m_output.at(ui->cmbOutput->currentIndex())); config->setProperty("lockAspect", ui->btnAspect->keepAspectRatio()); config->setProperty("transparency", ui->chkTransparent->isChecked()); config->setProperty("max_threshold", ui->sldMaxThreshold->value()); config->setProperty("min_threshold", ui->sldMinThreshold->value()); return config; } void KisWdgEdgeDetection::setConfiguration(const KisPropertiesConfigurationSP config) { ui->sldHorizontalRadius->setValue(config->getFloat("horizRadius", 1.0)); ui->sldVerticalRadius->setValue(config->getFloat("vertRadius", 1.0)); int index = 0; if (m_types.contains(config->getString("type", "prewitt"))) { index = m_types.indexOf(config->getString("type", "prewitt")); } ui->cmbType->setCurrentIndex(index); index = 0; if (m_output.contains(config->getString("output", "pythagorean"))) { index = m_output.indexOf(config->getString("output", "pythagorean")); } ui->cmbOutput->setCurrentIndex(index); ui->chkTransparent->setChecked(config->getBool("transparency", false)); ui->btnAspect->setKeepAspectRatio(config->getBool("lockAspect", false)); ui->sldMinThreshold->setValue(config->getInt("min_threshold", 100)); ui->sldMaxThreshold->setValue(config->getInt("max_threshold", 200)); } void KisWdgEdgeDetection::horizontalRadiusChanged(qreal r) { ui->sldHorizontalRadius->blockSignals(true); ui->sldHorizontalRadius->setValue(r); ui->sldHorizontalRadius->blockSignals(false); if (ui->btnAspect->keepAspectRatio()) { ui->sldVerticalRadius->blockSignals(true); ui->sldVerticalRadius->setValue(r); ui->sldVerticalRadius->blockSignals(false); } } void KisWdgEdgeDetection::verticalRadiusChanged(qreal r) { ui->sldVerticalRadius->blockSignals(true); ui->sldVerticalRadius->setValue(r); ui->sldVerticalRadius->blockSignals(false); if (ui->btnAspect->keepAspectRatio()) { ui->sldHorizontalRadius->blockSignals(true); ui->sldHorizontalRadius->setValue(r); ui->sldHorizontalRadius->blockSignals(false); } } void KisWdgEdgeDetection::maxThresholdChanged(int val) { if (ui->sldMinThreshold->value() > val) { ui->sldMinThreshold->setValue(val); } } void KisWdgEdgeDetection::minThresholdChanged(int val) { if (ui->sldMaxThreshold->value() < val) { ui->sldMaxThreshold->setValue(val); } } void KisWdgEdgeDetection::detectionTypeChanged(int index) { bool val = false; - if (index != 4) { + if (index == 3) { val = true; } - ui->sldMaxThreshold->setEnabled(val); ui->sldMinThreshold->setEnabled(val); + ui->cmbOutput->setEnabled(!val); } void KisWdgEdgeDetection::aspectLockChanged(bool v) { if (v) { ui->sldVerticalRadius->setValue(ui->sldHorizontalRadius->value()); } }