Krita Source Code Documentation
Loading...
Searching...
No Matches
randompickfilter.cpp
Go to the documentation of this file.
1/*
2 * This file is part of the KDE project
3 *
4 * SPDX-FileCopyrightText: 2005 Cyrille Berger <cberger@cberger.net>
5 *
6 * SPDX-License-Identifier: GPL-2.0-or-later
7 */
8
9#include "randompickfilter.h"
10#include <stdlib.h>
11#include <vector>
12#include <math.h>
13
14#include <QPoint>
15
16#include <kis_debug.h>
17
18#include <kpluginfactory.h>
19#include <klocalizedstring.h>
20
21#include <KoUpdater.h>
22
23#include <KoMixColorsOp.h>
25#include <kis_global.h>
26#include <kis_image.h>
27#include <kis_layer.h>
28#include <kis_paint_device.h>
31#include <kis_selection.h>
32#include <kis_types.h>
36
37#include "kis_wdg_random_pick.h"
38#include "ui_wdgrandompickoptions.h"
39#include <kis_iterator_ng.h>
41
42K_PLUGIN_FACTORY_WITH_JSON(KritaRandomPickFilterFactory, "kritarandompickfilter.json", registerPlugin<KritaRandomPickFilter>();)
43
44KritaRandomPickFilter::KritaRandomPickFilter(QObject *parent, const QVariantList &)
45 : QObject(parent)
46{
48}
49
53
59
60
62 const QRect& applyRect,
63 const KisFilterConfigurationSP config,
64 KoUpdater* progressUpdater
65 ) const
66{
67 Q_UNUSED(config);
68 Q_ASSERT(!device.isNull());
69
70 const KoColorSpace * cs = device->colorSpace();
71
72 QVariant value;
73 int level = (config && config->getProperty("level", value)) ? value.toInt() : 50;
74 int opacity = (config && config->getProperty("opacity", value)) ? value.toInt() : 100;
75 double windowsize = (config && config->getProperty("windowsize", value)) ? value.toDouble() : 2.5;
76
77 int seedThreshold = rand();
78 int seedH = rand();
79 int seedV = rand();
80
81 if (config) {
82 seedThreshold = config->getInt("seedThreshold", seedThreshold);
83 seedH = config->getInt("seedH", seedH);
84 seedV = config->getInt("seedV", seedV);
85 }
86 KisRandomGenerator2D randT(seedThreshold);
87 KisRandomGenerator2D randH(seedH);
88 KisRandomGenerator2D randV(seedV);
89
90 KisSequentialIteratorProgress dstIt(device, applyRect, progressUpdater);
92
93 double threshold = (100 - level) / 100.0;
94
95 qint16 weights[2];
96 weights[0] = (255 * opacity) / 100; weights[1] = 255 - weights[0];
97 const quint8* pixels[2];
98 KoMixColorsOp * mixOp = cs->mixColorsOp();
99 while (dstIt.nextPixel()) {
100 if (randT.doubleRandomAt(dstIt.x(), dstIt.y()) > threshold) {
101 int x = static_cast<int>(dstIt.x() + windowsize * (randH.doubleRandomAt(dstIt.x(), dstIt.y()) - 0.5));
102 int y = static_cast<int>(dstIt.y() + windowsize * (randV.doubleRandomAt(dstIt.x(), dstIt.y()) -0.5));
103 srcRA->moveTo(x, y);
104 pixels[0] = srcRA->oldRawData();
105 pixels[1] = dstIt.oldRawData();
106 mixOp->mixColors(pixels, weights, 2, dstIt.rawData());
107 }
108 }
109
110}
111
113{
114 Q_UNUSED(dev);
115 return new KisWdgRandomPick((KisFilter*)this, (QWidget*)parent);
116}
117
119{
120 KisFilterConfigurationSP config = factoryConfiguration(resourcesInterface);
121 config->setProperty("level", 50);
122 config->setProperty("windowsize", 2.5);
123 config->setProperty("opacity", 100);
124 config->setProperty("seedThreshold", rand());
125 config->setProperty("seedH", rand());
126 config->setProperty("seedV", rand());
127
128 return config;
129}
130
131QRect KisFilterRandomPick::neededRect(const QRect& rect, const KisFilterConfigurationSP config, int lod) const
132{
133 Q_UNUSED(lod);
134
135 QVariant value;
136 int windowsize = ceil((config && config->getProperty("windowsize", value)) ? value.toDouble() : 2.5);
137 return rect.adjusted(-windowsize, -windowsize, windowsize, windowsize);
138}
139
140QRect KisFilterRandomPick::changedRect(const QRect &rect, const KisFilterConfigurationSP config, int lod) const
141{
142 return neededRect(rect, config, lod);
143}
144
145#include "randompickfilter.moc"
float value(const T *src, size_t ch)
@ FULLY_INDEPENDENT
virtual const quint8 * oldRawData() const =0
KisConfigWidget * createConfigurationWidget(QWidget *parent, const KisPaintDeviceSP dev, bool useForMasks) const override
QRect neededRect(const QRect &rect, const KisFilterConfigurationSP config, int lod=0) const override
KisFilterConfigurationSP defaultConfiguration(KisResourcesInterfaceSP resourcesInterface) const override
QRect changedRect(const QRect &rect, const KisFilterConfigurationSP config, int lod=0) const override
void processImpl(KisPaintDeviceSP device, const QRect &applyRect, const KisFilterConfigurationSP config, KoUpdater *progressUpdater) const override
void add(KisFilterSP item)
static KisFilterRegistry * instance()
KisRandomConstAccessorSP createRandomConstAccessorNG() const
const KoColorSpace * colorSpace() const
virtual void moveTo(qint32 x, qint32 y)=0
ALWAYS_INLINE quint8 * rawData()
ALWAYS_INLINE int x() const
ALWAYS_INLINE const quint8 * oldRawData() const
ALWAYS_INLINE int y() const
bool isNull() const
KoMixColorsOp * mixColorsOp
virtual void mixColors(const quint8 *const *colors, const qint16 *weights, int nColors, quint8 *dst, int weightSum=255) const =0
KritaRandomPickFilter(QObject *parent, const QVariantList &)
K_PLUGIN_FACTORY_WITH_JSON(KritaASCCDLFactory, "kritaasccdl.json", registerPlugin< KritaASCCDL >();) KritaASCCDL
const KoID FiltersCategoryOtherId("other_filters", ki18nc("The category of filters that do not fit in a category. Noun.", "Other"))
virtual KisFilterConfigurationSP factoryConfiguration(KisResourcesInterfaceSP resourcesInterface) const
void setSupportsPainting(bool v)
void setColorSpaceIndependence(ColorSpaceIndependence v)
double doubleRandomAt(qint64 x, qint64 y)