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 #ifndef GAUSSBLURFILTER_H
48 #define GAUSSBLURFILTER_H
49
50 #include "convolutionfilter.h"
51 #include <cmath>
52
53 #ifndef M_PI
54 #define M_PI 3.1415926535897932384626433832795
55 #endif
56
57 class GaussBlurFilter : public ConvolutionFilter
58 {
59 public:
GaussBlurFilter()60 GaussBlurFilter() : ConvolutionFilter()
61 {
62 m_radius = 4.0;
63 }
64
65 ////
66 // INHERITED FROM ConvolutionFilter
67 ////
68 QVariant option(int option) const override;
69
setOption(int option,const QVariant & value)70 bool setOption(int option, const QVariant &value) override
71 {
72 bool ok = true;
73 switch (option) {
74 case QtImageFilter::Radius:
75 {
76 double radius = value.toDouble(&ok);
77 if (ok) m_radius = radius;
78 }
79 break;
80
81 default:
82 ok = ConvolutionFilter::setOption(option, value);
83 break;
84 }
85 return ok;
86 }
87
supportsOption(int option)88 bool supportsOption(int option) const override
89 {
90 if (option == QtImageFilter::Radius) return true;
91 return ConvolutionFilter::supportsOption(option);
92 }
93
94 QImage apply(const QImage &image, const QRect& clipRect ) const override;
95
name()96 QString name() const override { return QLatin1String("GaussBlur"); }
description()97 QString description() const override { return QObject::tr("A gaussian blur filter", "GaussBlurFilter"); }
98
99 private:
100 qreal m_radius;
101 };
102
103
Gauss2DFunction(int x,int y,qreal deviance)104 static qreal Gauss2DFunction(int x, int y, qreal deviance)
105 {
106 /**
107 * A 2-D gaussian distribution has the shape:
108 *
109 * 1 -(x*x + y*y)/(2*dev*dev)
110 * G(x,y) = ---------- * e^
111 * 2*PI*dev^2
112 *
113 * see http://www.cee.hw.ac.uk/hipr/html/gsmooth.html for a more readable version
114 */
115 return exp(-(x*x + y*y)/(2*deviance*deviance))/(2*M_PI*deviance*deviance);
116 }
117
option(int option)118 QVariant GaussBlurFilter::option(int option) const
119 {
120 if (option == QtImageFilter::Radius) return true;
121 return ConvolutionFilter::option(option);
122 }
123
apply(const QImage & image,const QRect & clipRect)124 QImage GaussBlurFilter::apply(const QImage &image, const QRect& clipRect ) const
125 {
126 if (m_radius > 0.0) {
127 int uRadius = (int)ceil(m_radius);
128
129 double deviance = sqrt(-m_radius*m_radius/(2*log(1/255.0)));
130 QtMatrix<double> matLeft(2 * uRadius + 1, 1);
131
132 for (int x = -uRadius; x <=uRadius; x++) {
133 matLeft.setData(uRadius + x, 0, Gauss2DFunction(x, 0, deviance));
134 }
135 double scalar = matLeft.at(uRadius, 0);
136 matLeft*=(255.0/scalar);
137 QtMatrix<double> matRight = matLeft.transposed();
138
139 QtConvolutionKernelMatrix integerMatrixLeft = convertMatrixBasetype<int,double>(matLeft);
140 QtConvolutionKernelMatrix integerMatrixRight = convertMatrixBasetype<int,double>(matRight);
141
142 auto localThis = const_cast<GaussBlurFilter*>(this);
143 localThis->addKernel(integerMatrixLeft, m_channels, m_borderPolicy);
144 localThis->addKernel(integerMatrixRight, m_channels, m_borderPolicy);
145 }
146 return ConvolutionFilter::apply(image, clipRect);
147 }
148
149 #endif //GAUSSBLURFILTER_H
150
151