File indexing completed on 2024-06-16 04:16:43
0001 /* 0002 * This file is part of the KDE project 0003 * 0004 * SPDX-FileCopyrightText: 2005 Cyrille Berger <cberger@cberger.net> 0005 * 0006 * SPDX-License-Identifier: GPL-2.0-or-later 0007 */ 0008 0009 #include "randompickfilter.h" 0010 #include <stdlib.h> 0011 #include <vector> 0012 #include <math.h> 0013 0014 #include <QPoint> 0015 0016 #include <kis_debug.h> 0017 0018 #include <kpluginfactory.h> 0019 #include <klocalizedstring.h> 0020 0021 #include <KoUpdater.h> 0022 0023 #include <KoMixColorsOp.h> 0024 #include <filter/kis_filter_registry.h> 0025 #include <kis_global.h> 0026 #include <kis_image.h> 0027 #include <kis_layer.h> 0028 #include <kis_paint_device.h> 0029 #include <kis_random_accessor_ng.h> 0030 #include <kis_random_generator.h> 0031 #include <kis_selection.h> 0032 #include <kis_types.h> 0033 #include <filter/kis_filter_category_ids.h> 0034 #include <filter/kis_filter_configuration.h> 0035 #include <kis_processing_information.h> 0036 0037 #include "kis_wdg_random_pick.h" 0038 #include "ui_wdgrandompickoptions.h" 0039 #include <kis_iterator_ng.h> 0040 #include <KisSequentialIteratorProgress.h> 0041 0042 K_PLUGIN_FACTORY_WITH_JSON(KritaRandomPickFilterFactory, "kritarandompickfilter.json", registerPlugin<KritaRandomPickFilter>();) 0043 0044 KritaRandomPickFilter::KritaRandomPickFilter(QObject *parent, const QVariantList &) 0045 : QObject(parent) 0046 { 0047 KisFilterRegistry::instance()->add(new KisFilterRandomPick()); 0048 } 0049 0050 KritaRandomPickFilter::~KritaRandomPickFilter() 0051 { 0052 } 0053 0054 KisFilterRandomPick::KisFilterRandomPick() : KisFilter(id(), FiltersCategoryOtherId, i18n("&Random Pick...")) 0055 { 0056 setColorSpaceIndependence(FULLY_INDEPENDENT); 0057 setSupportsPainting(true); 0058 } 0059 0060 0061 void KisFilterRandomPick::processImpl(KisPaintDeviceSP device, 0062 const QRect& applyRect, 0063 const KisFilterConfigurationSP config, 0064 KoUpdater* progressUpdater 0065 ) const 0066 { 0067 Q_UNUSED(config); 0068 Q_ASSERT(!device.isNull()); 0069 0070 const KoColorSpace * cs = device->colorSpace(); 0071 0072 QVariant value; 0073 int level = (config && config->getProperty("level", value)) ? value.toInt() : 50; 0074 int opacity = (config && config->getProperty("opacity", value)) ? value.toInt() : 100; 0075 double windowsize = (config && config->getProperty("windowsize", value)) ? value.toDouble() : 2.5; 0076 0077 int seedThreshold = rand(); 0078 int seedH = rand(); 0079 int seedV = rand(); 0080 0081 if (config) { 0082 seedThreshold = config->getInt("seedThreshold", seedThreshold); 0083 seedH = config->getInt("seedH", seedH); 0084 seedV = config->getInt("seedV", seedV); 0085 } 0086 KisRandomGenerator randT(seedThreshold); 0087 KisRandomGenerator randH(seedH); 0088 KisRandomGenerator randV(seedV); 0089 0090 KisSequentialIteratorProgress dstIt(device, applyRect, progressUpdater); 0091 KisRandomConstAccessorSP srcRA = device->createRandomConstAccessorNG(); 0092 0093 double threshold = (100 - level) / 100.0; 0094 0095 qint16 weights[2]; 0096 weights[0] = (255 * opacity) / 100; weights[1] = 255 - weights[0]; 0097 const quint8* pixels[2]; 0098 KoMixColorsOp * mixOp = cs->mixColorsOp(); 0099 while (dstIt.nextPixel()) { 0100 if (randT.doubleRandomAt(dstIt.x(), dstIt.y()) > threshold) { 0101 int x = static_cast<int>(dstIt.x() + windowsize * (randH.doubleRandomAt(dstIt.x(), dstIt.y()) - 0.5)); 0102 int y = static_cast<int>(dstIt.y() + windowsize * (randV.doubleRandomAt(dstIt.x(), dstIt.y()) -0.5)); 0103 srcRA->moveTo(x, y); 0104 pixels[0] = srcRA->oldRawData(); 0105 pixels[1] = dstIt.oldRawData(); 0106 mixOp->mixColors(pixels, weights, 2, dstIt.rawData()); 0107 } 0108 } 0109 0110 } 0111 0112 KisConfigWidget * KisFilterRandomPick::createConfigurationWidget(QWidget* parent, const KisPaintDeviceSP dev, bool) const 0113 { 0114 Q_UNUSED(dev); 0115 return new KisWdgRandomPick((KisFilter*)this, (QWidget*)parent); 0116 } 0117 0118 KisFilterConfigurationSP KisFilterRandomPick::defaultConfiguration(KisResourcesInterfaceSP resourcesInterface) const 0119 { 0120 KisFilterConfigurationSP config = factoryConfiguration(resourcesInterface); 0121 config->setProperty("level", 50); 0122 config->setProperty("windowsize", 2.5); 0123 config->setProperty("opacity", 100); 0124 config->setProperty("seedThreshold", rand()); 0125 config->setProperty("seedH", rand()); 0126 config->setProperty("seedV", rand()); 0127 0128 return config; 0129 } 0130 0131 QRect KisFilterRandomPick::neededRect(const QRect& rect, const KisFilterConfigurationSP config, int lod) const 0132 { 0133 Q_UNUSED(lod); 0134 0135 QVariant value; 0136 int windowsize = ceil((config && config->getProperty("windowsize", value)) ? value.toDouble() : 2.5); 0137 return rect.adjusted(-windowsize, -windowsize, windowsize, windowsize); 0138 } 0139 0140 QRect KisFilterRandomPick::changedRect(const QRect &rect, const KisFilterConfigurationSP config, int lod) const 0141 { 0142 return neededRect(rect, config, lod); 0143 } 0144 0145 #include "randompickfilter.moc"