1 /****************************************************************************
2 **
3 ** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
6 **
7 ** This file is part of a Qt Solutions component.
8 **
9 ** Commercial Usage
10 ** Licensees holding valid Qt Commercial licenses may use this file in
11 ** accordance with the Qt Solutions Commercial License Agreement provided
12 ** with the Software or, alternatively, in accordance with the terms
13 ** contained in a written agreement between you and Nokia.
14 **
15 ** GNU Lesser General Public License Usage
16 ** Alternatively, this file may be used under the terms of the GNU Lesser
17 ** General Public License version 2.1 as published by the Free Software
18 ** Foundation and appearing in the file LICENSE.LGPL included in the
19 ** packaging of this file. Please review the following information to
20 ** ensure the GNU Lesser General Public License version 2.1 requirements
21 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
22 **
23 ** In addition, as a special exception, Nokia gives you certain
24 ** additional rights. These rights are described in the Nokia Qt LGPL
25 ** Exception version 1.1, included in the file LGPL_EXCEPTION.txt in this
26 ** package.
27 **
28 ** GNU General Public License Usage
29 ** Alternatively, this file may be used under the terms of the GNU
30 ** General Public License version 3.0 as published by the Free Software
31 ** Foundation and appearing in the file LICENSE.GPL included in the
32 ** packaging of this file. Please review the following information to
33 ** ensure the GNU General Public License version 3.0 requirements will be
34 ** met: http://www.gnu.org/copyleft/gpl.html.
35 **
36 ** Please note Third Party Software included with Qt Solutions may impose
37 ** additional restrictions and it is the user's responsibility to ensure
38 ** that they have met the licensing requirements of the GPL, LGPL, or Qt
39 ** Solutions Commercial license and the relevant license of the Third
40 ** Party Software they are using.
41 **
42 ** If you are unsure which license is appropriate for your use, please
43 ** contact Nokia at qt-info@nokia.com.
44 **
45 ****************************************************************************/
46
47 #include "qtimagefilter.h"
48 #include "convolutionfilter.h"
49 #include "gaussfilter.h"
50 #include "punchfilter.h"
51 #include <QtCore/QMap>
52 #include <QtCore/QByteArray>
53
createGaussianBlurFilter()54 QtImageFilter *createGaussianBlurFilter()
55 {
56 return reinterpret_cast<QtImageFilter*>(new GaussBlurFilter());
57 }
58
createDefocusFilter()59 QtImageFilter *createDefocusFilter()
60 {
61 static int kernelmatrix[ 9 ] =
62 { 1, 1, 1,
63 1, -7, 1,
64 1, 1, 1 };
65 auto filter = new ConvolutionFilter();
66 filter->setName(QLatin1String("Defocus"));
67 filter->setDescription(QObject::tr("Blurs the image", "ConvolutionFilter"));
68 filter->addKernel(QtConvolutionKernelMatrix(kernelmatrix, 3, 3), ConvolutionFilter::RGB, ConvolutionFilter::Extend);
69 return reinterpret_cast<QtImageFilter*>(filter);
70 }
71
createHighlightFilter()72 QtImageFilter *createHighlightFilter()
73 {
74 static int kernelmatrix[ 25 ] =
75 { -1, 0, 0, 0, 0,
76 0, 0, 0, 0, 0,
77 0, 0, 0, 0, 0,
78 0, 0, 0, 0, 0,
79 0, 0, 0, 0, 2 };
80 auto filter = new ConvolutionFilter();
81 filter->setName(QLatin1String("Highlight"));
82 filter->addKernel(QtConvolutionKernelMatrix(kernelmatrix, 5, 5), ConvolutionFilter::RGB, ConvolutionFilter::Extend, 1, 0);
83 return reinterpret_cast<QtImageFilter*>(filter);
84 }
85
createSharpenFilter()86 QtImageFilter *createSharpenFilter()
87 {
88 static int kernelmatrix[ 25 ] =
89 { -1, -1, -1, -1, -1,
90 -1, 2, 2, 2, -1,
91 -1, 2, 8, 2, -1,
92 -1, 2, 2, 2, -1,
93 -1, -1, -1, -1, -1 };
94 auto filter = new ConvolutionFilter();
95 filter->setName(QLatin1String("Sharpen"));
96 filter->setDescription(QObject::tr("Sharpens the image","ConvolutionFilter"));
97 filter->addKernel(QtConvolutionKernelMatrix(kernelmatrix, 5, 5), ConvolutionFilter::RGB, ConvolutionFilter::Extend, 8, 0);
98 return reinterpret_cast<QtImageFilter*>(filter);
99 }
100
createSharpenMoreFilter()101 QtImageFilter *createSharpenMoreFilter()
102 {
103 static int kernelmatrix[ 9 ] =
104 { -1, -1, -1,
105 -1, 9, -1,
106 -1, -1, -1 };
107 auto filter = new ConvolutionFilter();
108 filter->setName(QLatin1String("SharpenMore"));
109 filter->setDescription(QObject::tr("Sharpens the image more","ConvolutionFilter"));
110 filter->addKernel(QtConvolutionKernelMatrix(kernelmatrix, 3, 3), ConvolutionFilter::RGB, ConvolutionFilter::Extend, 1, 0);
111 return reinterpret_cast<QtImageFilter*>(filter);
112 }
113
createSharpenEvenMoreFilter()114 QtImageFilter *createSharpenEvenMoreFilter()
115 {
116 static int kernelmatrix[ 9 ] =
117 { -1, -2, -1,
118 -2, 13, -2,
119 -1, -2, -1 };
120 auto filter = new ConvolutionFilter();
121 filter->setName(QLatin1String("SharpenEvenMore"));
122 filter->setDescription(QObject::tr("Sharpens the image even more","ConvolutionFilter"));
123 filter->addKernel(QtConvolutionKernelMatrix(kernelmatrix, 3, 3), ConvolutionFilter::RGB, ConvolutionFilter::Extend, 1, 0);
124 return reinterpret_cast<QtImageFilter*>(filter);
125 }
126
createBigEdgeFilter()127 QtImageFilter *createBigEdgeFilter()
128 {
129 static int kernelmatrix[ 25 ] =
130 { -2, -2, -2, -2, -2,
131 -2, -3, -3, -3, -2,
132 -2, -3, 53, -3, -2,
133 -2, -3, -3, -3, -2,
134 -2, -2, -2, -2, -2 };
135 auto filter = new ConvolutionFilter();
136 filter->setName(QLatin1String("BigEdge"));
137 filter->setDescription(QObject::tr("Creates big edges","ConvolutionFilter"));
138 filter->addKernel(QtConvolutionKernelMatrix(kernelmatrix, 5, 5), ConvolutionFilter::RGB, ConvolutionFilter::Extend, 1, 0);
139 return reinterpret_cast<QtImageFilter*>(filter);
140 }
141
createEmbossFilter()142 QtImageFilter *createEmbossFilter()
143 {
144 static int kernelmatrix[ 9 ] =
145 { -1, -1, 0,
146 -1, 0, 1,
147 0, 1, 1 };
148 auto filter = new ConvolutionFilter();
149 filter->setName(QLatin1String("Emboss"));
150 filter->setDescription(QObject::tr("Creates an emboss effect on the image, resulting in a greyish image","ConvolutionFilter"));
151 filter->addKernel(QtConvolutionKernelMatrix(kernelmatrix, 3, 3), ConvolutionFilter::RGB, ConvolutionFilter::Extend, 1, 128);
152 return reinterpret_cast<QtImageFilter*>(filter);
153 }
154
createEmbossColorFilter()155 QtImageFilter *createEmbossColorFilter()
156 {
157 static int kernelmatrix[9] =
158 { -1, -1, 0,
159 -1, 1, 1,
160 0, 1, 1 };
161 auto filter = new ConvolutionFilter();
162 filter->setName(QLatin1String("EmbossColor"));
163 filter->setDescription(QObject::tr("Creates an emboss effect on the image, while keeping most of the colours","ConvolutionFilter"));
164 filter->addKernel(QtConvolutionKernelMatrix(kernelmatrix, 3, 3), ConvolutionFilter::RGB, ConvolutionFilter::Extend, 1, 0);
165 return reinterpret_cast<QtImageFilter*>(filter);
166 }
167
createEdgeDetectFilter()168 QtImageFilter *createEdgeDetectFilter()
169 {
170 static int kernelmatrix[ 9 ] =
171 { -5, -2, -5,
172 -5, 39, -5,
173 -5, -5, -5 };
174 auto filter = new ConvolutionFilter();
175 filter->setName(QLatin1String("EdgeDetect"));
176 filter->setDescription(QObject::tr("Creates a filter that enables you to detect edges easily.","ConvolutionFilter"));
177 filter->addKernel(QtConvolutionKernelMatrix(kernelmatrix, 3, 3), ConvolutionFilter::RGB, ConvolutionFilter::Extend, 1, 50);
178 return reinterpret_cast<QtImageFilter*>(filter);
179 }
180
createNegativeFilter()181 QtImageFilter *createNegativeFilter()
182 {
183 static int kernelmatrix[ 1 ] =
184 { -1 };
185 auto filter = new ConvolutionFilter();
186 filter->setName(QLatin1String("Negative"));
187 filter->setDescription(QObject::tr("Negates color channel(s).","ConvolutionFilter"));
188 filter->addKernel(QtConvolutionKernelMatrix(kernelmatrix, 1, 1), ConvolutionFilter::RGB, ConvolutionFilter::Extend, 1, 255);
189 return reinterpret_cast<QtImageFilter*>(filter);
190 }
191
createRemoveChannelFilter()192 QtImageFilter *createRemoveChannelFilter()
193 {
194 static int kernelmatrix[ 1 ] =
195 { 0 };
196 auto filter = new ConvolutionFilter();
197 filter->setName(QLatin1String("RemoveChannel"));
198 filter->setDescription(QObject::tr("Removes channel(s). I.e sets the value of each channel it is processing to 0.","ConvolutionFilter"));
199 filter->addKernel(QtConvolutionKernelMatrix(kernelmatrix, 1, 1), ConvolutionFilter::RGBA, ConvolutionFilter::Extend, 1, 0);
200 return reinterpret_cast<QtImageFilter*>(filter);
201 }
202
createConvolutionFilter()203 QtImageFilter *createConvolutionFilter()
204 {
205 static int kernelmatrix[ 1 ] =
206 { 1 };
207 auto filter = new ConvolutionFilter();
208 filter->setName(QLatin1String("ConvolutionFilter"));
209 filter->setDescription(QObject::tr("Generic convolutionfilter."));
210 filter->addKernel(QtConvolutionKernelMatrix(kernelmatrix, 1, 1), ConvolutionFilter::RGBA, ConvolutionFilter::Extend, 1, 0);
211 return reinterpret_cast<QtImageFilter*>(filter);
212 }
213
createPunchFilter()214 QtImageFilter *createPunchFilter()
215 {
216 return reinterpret_cast<QtImageFilter*>(new PunchFilter());
217 }
218
219 //typedef QtImageFilter*(*FnFactory)(void);
220
221 static QMap<QByteArray, QtImageFilterFactory::ImageFilterFactoryFunction> g_availableFilters;
222
registerDefaultImageFilters()223 static void registerDefaultImageFilters()
224 {
225 g_availableFilters.insert("GaussianBlur", &createGaussianBlurFilter);
226 g_availableFilters.insert("Defocus", &createDefocusFilter);
227 g_availableFilters.insert("Highlight", &createHighlightFilter);
228 g_availableFilters.insert("Sharpen", &createSharpenFilter);
229 g_availableFilters.insert("SharpenMore", &createSharpenMoreFilter);
230 g_availableFilters.insert("SharpenEvenMore", &createSharpenEvenMoreFilter);
231 g_availableFilters.insert("BigEdge", &createBigEdgeFilter);
232 g_availableFilters.insert("Emboss", &createEmbossFilter);
233 g_availableFilters.insert("EmbossColor", &createEmbossColorFilter);
234 g_availableFilters.insert("EdgeDetect", &createEdgeDetectFilter);
235 g_availableFilters.insert("Negative", &createNegativeFilter);
236 g_availableFilters.insert("RemoveChannel", &createRemoveChannelFilter);
237 g_availableFilters.insert("Punch", &createPunchFilter);
238 g_availableFilters.insert("ConvolutionFilter", &createConvolutionFilter);
239 }
240 /*!
241 \class QtImageFilterFactory
242
243 \brief The QtImageFilterFactory class is used to create and manage
244 QtImageFilter objects.
245
246 QtImageFilterFactory is part of the QtImageFilters solution, and is
247 used to create instances of the registered image filters. The
248 framework supports many popular image filters by default, among
249 these are gaussian blurring, embossing (see image below),
250 sharpening, defocus, punch/pinch and convolution filters.
251
252 \image lena-edge.jpg
253
254 The documentation for the createImageFilter() function provides a
255 complete list of all the supported image filters.
256
257 Developers can extend the framework with their own custom image
258 filters by deriving from the QtImageFilter class. A list of the
259 currently registered filters, including custom filters, can be
260 retrieved using the imageFilterList() function.
261
262 When creating a custom image filter, it must be registered using
263 the registerImageFilter() function before instances can be created
264 using the createImageFilter() function. For example:
265
266 \quotefromfile ../examples/imagetool/imagetoolwidget.cpp
267 \skipto qtRegisterImageFilter
268 \printline qtRegisterImageFilter
269 \skipto QStringList
270 \printuntil m_imageFilters
271
272 The registerImageFilter() function requires an
273 ImageFilterFactoryFunction pointer and the name of the image
274 filter. ImageFilterFactoryFunction is a type definition for a
275 function that can create and return a QtImageFilter object of a
276 given filter type.
277
278 Due to compiler limitations, the template version of the
279 registerImageFilter() function is not available on all
280 platforms (the related qtRegisterImageFilter() function is
281 provided as a work-around for the MSVC 6 compiler).
282
283 \sa QtImageFilter
284 */
285
286 /*!
287 \typedef QtImageFilterFactory::ImageFilterFactoryFunction
288
289 This is a type definition for a pointer to a function with the
290 following signature:
291
292 \code
293 QtImageFilter *myFilterFactoryFunc(void);
294 \endcode
295
296 \sa registerImageFilter()
297 */
298 /*!
299 Creates an instance of the image filter specified by the given \a
300 name. Returns true if the image filter was successfully
301 initialized; otherwise false.
302
303 The given filter must be registered using the
304 registerImageFilter() function. The following image filters are
305 registered by default:
306
307 \table
308 \header
309 \o Filter Name
310 \o Filter Operation
311 \o Supported Options
312 \row
313 \o ConvolutionFilter
314 \o Creates a custom convolutionfilter
315 \o ConvolutionKernelMatrix, FilterChannels, FilterBorderPolicy, ConvolutionDivisor, ConvolutionBias
316 \row
317 \o GaussianBlur
318 \o Creates a gaussian blur filter.
319 \o Radius, FilterChannels, FilterBorderPolicy
320 \row
321 \o Defocus
322 \o Blurs the image.
323 \o FilterChannels, FilterBorderPolicy
324 \row
325 \o Highlight
326 \o
327 \o FilterChannels, FilterBorderPolicy
328 \row
329 \o Sharpen
330 \o Sharpens the image
331 \o FilterChannels, FilterBorderPolicy
332 \row
333 \o SharpenMore
334 \o Sharpens the image
335 \o FilterChannels, FilterBorderPolicy
336 \row
337 \o SharpenEvenMore
338 \o Sharpens the image
339 \o FilterChannels, FilterBorderPolicy
340 \row
341 \o EdgeDetect
342 \o Edge detection filter
343 \o
344 \row
345 \o BigEdge
346 \o Edge detection filter (gives thicker edges)
347 \o FilterChannels, FilterBorderPolicy
348 \row
349 \o Emboss
350 \o Embosses the image (does not preserve color information)
351 \o FilterChannels, FilterBorderPolicy
352 \row
353 \o EmbossColor
354 \o Embosses the image (tries to preserve color information)
355 \o FilterChannels, FilterBorderPolicy
356 \row
357 \o Negative
358 \o Negates a color channel.
359 \o FilterChannels, FilterBorderPolicy
360 \row
361 \o RemoveChannel
362 \o Removes a color/alpha channel
363 \o FilterChannels, FilterBorderPolicy
364 \row
365 \o Punch
366 \o Distorts an image using a pinch/punch effect
367 \o Center, Radius, Force. Force should be in the interval [-1.0, 1.0]
368 \endtable
369
370 \sa registerImageFilter()
371 */
createImageFilter(const QString & name)372 QtImageFilter *QtImageFilterFactory::createImageFilter(const QString &name)
373 {
374 if (g_availableFilters.isEmpty()) {
375 registerDefaultImageFilters();
376 }
377
378 ImageFilterFactoryFunction fnFactory = g_availableFilters.value(name.toLatin1());
379 return fnFactory ? fnFactory() : nullptr;
380 }
381
382 /*!
383 Returns a list of the currently registered image filters.
384
385 \sa registerImageFilter()
386 */
imageFilterList()387 QStringList QtImageFilterFactory::imageFilterList()
388 {
389 QStringList ss;
390 if (g_availableFilters.isEmpty()) {
391 registerDefaultImageFilters();
392 }
393
394 for (QMap<QByteArray, ImageFilterFactoryFunction>::iterator it = g_availableFilters.begin(); it != g_availableFilters.end(); ++it) {
395 ss.append(QLatin1String(it.key()));
396 }
397 return ss;
398 }
399
400 /*!
401 \fn void QtImageFilterFactory::registerImageFilter(const QString &name, ImageFilterFactoryFunction function)
402
403 Registers an image filter factory function, where the given \a
404 name is associated with the specified factory \a function
405 returning a image filter object of the specified type.
406
407 \sa imageFilterList(), createImageFilter()
408 */
registerImageFilter(const QString & name,ImageFilterFactoryFunction func)409 void QtImageFilterFactory::registerImageFilter(const QString &name, ImageFilterFactoryFunction func)
410 {
411 if (g_availableFilters.isEmpty()) {
412 registerDefaultImageFilters();
413 }
414 g_availableFilters.insert(name.toLatin1(), func);
415 }
416
417 /*!
418 \fn QtImageFilter *QtImageFilterFactory::automaticFilterCreator()
419 \internal
420
421 This is a template function that creates a factory function for
422 creating a QtImageFilter object of type \c{T}. For example:
423
424 This function is also used as a helper function for the
425 registerImageFilter(const QString &name) function.
426
427 \warning Due to compiler limitations, this function is not
428 available on all platforms. In particular it is not available with
429 MSVC 6; use qtAutomaticFilterCreator() instead to support that
430 compiler version.
431
432 \sa registerImageFilter()
433 */
434
435 /*!
436 \fn QtImageFilter *qtAutomaticFilterCreator(const T* dummy = 0)
437 \relates QtImageFilterFactory
438 \internal
439
440 This function is equivalent to
441 QtImageFilterFactory::automaticFilterCreator()
442
443 It is provided as a work-around for the MSVC 6 compiler, which
444 doesn't support member template functions. There is no need to
445 pass any value for the \a dummy parameter; it is only there
446 because of an MSVC 6 limitation.
447
448 \sa QtImageFilterFactory::automaticFilterCreator()
449 */
450
451 /*!
452 \fn void QtImageFilterFactory::registerImageFilter(const QString &name)
453
454 This is a template function, registering the image filter with the
455 given \a name together with a factory function that returns a new
456 instance of an image filter of type \c{T}. For example:
457
458 \code
459 registerImageFilter<MirrorFilter>(QLatin1String("MirrorFilter"));
460 \endcode
461
462 \warning Due to compiler limitations, this function is not
463 available on all platforms. In particular it is not available with
464 MSVC 6; use qtRegisterImageFilter() instead to support that
465 compiler version.
466
467 \sa createImageFilter()
468 */
469
470 /*!
471 \fn qtRegisterImageFilter(const QString &name, T* dummy )
472 \relates QtImageFilterFactory
473
474 This function is equivalent to the template version of the
475 QtImageFilterFactory::registerImageFilter() function.It registers
476 the image filter with the given \a name together with a factory
477 function that returns a new instance of the image filter.
478
479 It is provided as a work-around for the MSVC 6 compiler, which
480 doesn't support member template functions. Note that there is no
481 need to pass any value for the \a dummy parameter; it is only
482 there because of an MSVC 6 limitation.
483
484 \sa QtImageFilterFactory::registerImageFilter()
485 */
486
487