Update copyright year in Digia's license headers
[qt:qtgraphicaleffects.git] / src / effects / GaussianBlur.qml
1 /****************************************************************************
2 **
3 ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the Qt Graphical Effects module.
7 **
8 ** $QT_BEGIN_LICENSE:BSD$
9 ** You may use this file under the terms of the BSD license as follows:
10 **
11 ** "Redistribution and use in source and binary forms, with or without
12 ** modification, are permitted provided that the following conditions are
13 ** met:
14 **   * Redistributions of source code must retain the above copyright
15 **     notice, this list of conditions and the following disclaimer.
16 **   * Redistributions in binary form must reproduce the above copyright
17 **     notice, this list of conditions and the following disclaimer in
18 **     the documentation and/or other materials provided with the
19 **     distribution.
20 **   * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
21 **     of its contributors may be used to endorse or promote products derived
22 **     from this software without specific prior written permission.
23 **
24 **
25 ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28 ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31 ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
36 **
37 ** $QT_END_LICENSE$
38 **
39 ****************************************************************************/
40
41 import QtQuick 2.0
42 import "private"
43
44 /*!
45     \qmltype GaussianBlur
46     \inqmlmodule QtGraphicalEffects 1.0
47     \since QtGraphicalEffects 1.0
48     \inherits QtQuick2::Item
49     \ingroup qtgraphicaleffects-blur
50     \brief Applies a higher quality blur effect.
51
52     GaussianBlur effect softens the image by blurring it with an algorithm that
53     uses the Gaussian function to calculate the effect. The effect produces
54     higher quality than \l{QtGraphicalEffects1::FastBlur}{FastBlur}, but is
55     slower to render.
56
57     \table
58     \header
59         \li Source
60         \li Effect applied
61     \row
62         \li \image Original_bug.png
63         \li \image GaussianBlur_bug.png
64     \endtable
65
66     \section1 Example
67
68     The following example shows how to apply the effect.
69     \snippet GaussianBlur-example.qml example
70
71 */
72 Item {
73     id: rootItem
74
75     /*!
76         This property defines the source item that is going to be blurred.
77     */
78     property variant source
79
80     /*!
81         This property defines the distance of the neighboring pixels which
82         affect the blurring of an individual pixel. A larger radius increases
83         the blur effect.
84
85         Depending on the radius value, value of the
86         \l{GaussianBlur::samples}{samples} should be set to sufficiently large
87         to ensure the visual quality.
88
89         The value ranges from 0.0 (no blur) to inf. By default, the property is
90         set to \c 0.0 (no blur).
91
92         \table
93         \header
94         \li Output examples with different radius values
95         \li
96         \li
97         \row
98             \li \image GaussianBlur_radius1.png
99             \li \image GaussianBlur_radius2.png
100             \li \image GaussianBlur_radius3.png
101         \row
102             \li \b { radius: 0 }
103             \li \b { radius: 4 }
104             \li \b { radius: 8 }
105         \row
106             \li \l samples: 16
107             \li \l samples: 16
108             \li \l samples: 16
109         \row
110             \li \l deviation: 3
111             \li \l deviation: 3
112             \li \l deviation: 3
113         \endtable
114
115     */
116     property real radius: 0.0
117
118     /*!
119         This property defines how many samples are taken per pixel when blur
120         calculation is done. Larger value produces better quality, but is slower
121         to render.
122
123         Ideally, this value should be twice as large as the highest required
124         radius value, for example, if the radius is animated between 0.0 and
125         4.0, samples should be set to 8.
126
127         The value ranges from 0 to 32. By default, the property is set to \c 0.
128
129         This property is not intended to be animated. Changing this property may
130         cause the underlying OpenGL shaders to be recompiled.
131
132     */
133     property int samples: 0
134
135     /*!
136         This property is a parameter to the gaussian function that is used when
137         calculating neighboring pixel weights for the blurring. A larger
138         deviation causes image to appear more blurry, but it also reduces the
139         quality of the blur. A very large deviation value causes the effect to
140         look a bit similar to what, for exmple, a box blur algorithm produces. A
141         too small deviation values makes the effect insignificant for the pixels
142         near the radius.
143
144         \inlineimage GaussianBlur_deviation_graph.png
145         \caption The image above shows the Gaussian function with two different
146         deviation values, yellow (1) and cyan (2.7). The y-axis shows the
147         weights, the x-axis shows the pixel distance.
148
149         The value ranges from 0.0 (no deviation) to inf (maximum deviation). By
150         default, devaition is binded to radius. When radius increases, deviation
151         is automatically increased linearly. With the radius value of 8, the
152         deviation default value becomes approximately 2.7034. This value
153         produces a compromise between the blur quality and overall blurriness.
154
155         \table
156         \header
157         \li Output examples with different deviation values
158         \li
159         \li
160         \row
161             \li \image GaussianBlur_deviation1.png
162             \li \image GaussianBlur_deviation2.png
163             \li \image GaussianBlur_deviation3.png
164         \row
165             \li \b { deviation: 1 }
166             \li \b { deviation: 2 }
167             \li \b { deviation: 4 }
168         \row
169             \li \l radius: 8
170             \li \l radius: 8
171             \li \l radius: 8
172         \row
173             \li \l samples: 16
174             \li \l samples: 16
175             \li \l samples: 16
176         \endtable
177
178     */
179     property real deviation: (radius + 1) / 3.3333
180
181     /*!
182         This property defines the blur behavior near the edges of the item,
183         where the pixel blurring is affected by the pixels outside the source
184         edges.
185
186         If the property is set to \c true, the pixels outside the source are
187         interpreted to be transparent, which is similar to OpenGL
188         clamp-to-border extension. The blur is expanded slightly outside the
189         effect item area.
190
191         If the property is set to \c false, the pixels outside the source are
192         interpreted to contain the same color as the pixels at the edge of the
193         item, which is similar to OpenGL clamp-to-edge behavior. The blur does
194         not expand outside the effect item area.
195
196         By default, the property is set to \c false.
197
198         \table
199         \header
200         \li Output examples with different transparentBorder values
201         \li
202         \li
203         \row
204             \li \image GaussianBlur_transparentBorder1.png
205             \li \image GaussianBlur_transparentBorder2.png
206         \row
207             \li \b { transparentBorder: false }
208             \li \b { transparentBorder: true }
209         \row
210             \li \l radius: 8
211             \li \l radius: 8
212         \row
213             \li \l samples: 16
214             \li \l samples: 16
215         \row
216             \li \l deviation: 2.7
217             \li \l deviation: 2.7
218         \endtable
219
220     */
221     property bool transparentBorder: false
222
223     /*!
224         This property allows the effect output pixels to be cached in order to
225         improve the rendering performance.
226         Every time the source or effect properties are changed, the pixels in
227         the cache must be updated. Memory consumption is increased, because an
228         extra buffer of memory is required for storing the effect output.
229
230         It is recommended to disable the cache when the source or the effect
231         properties are animated.
232
233         By default, the property is set to \c false.
234
235     */
236     property bool cached: false
237
238     SourceProxy {
239         id: sourceProxy
240         input: rootItem.source
241         sourceRect: rootItem.transparentBorder ? Qt.rect(-1, -1, parent.width + 2.0, parent.height + 2.0) : Qt.rect(0, 0, 0, 0)
242     }
243
244     ShaderEffectSource {
245         id: cacheItem
246         anchors.fill: verticalBlur
247         visible: rootItem.cached
248         smooth: true
249         sourceItem: verticalBlur
250         live: true
251         hideSource: visible
252     }
253
254     GaussianDirectionalBlur {
255         id: verticalBlur
256         x: transparentBorder ? -maximumRadius - 1 : 0
257         y: transparentBorder ? -maximumRadius - 1 : 0
258         width: horizontalBlur.width
259         height: horizontalBlur.height
260
261         horizontalStep: 0.0
262         verticalStep: 1.0 / parent.height
263
264         source: ShaderEffectSource {
265             id: horizontalBlurSource
266             sourceItem: horizontalBlur
267             hideSource: true
268             visible: false
269             smooth: true
270         }
271
272         deviation: rootItem.deviation
273         radius: rootItem.radius
274         maximumRadius: rootItem.samples * 0.5
275         transparentBorder: rootItem.transparentBorder
276     }
277
278     GaussianDirectionalBlur {
279         id: horizontalBlur
280         width: transparentBorder ? parent.width + 2 * maximumRadius + 2 : parent.width
281         height: transparentBorder ? parent.height + 2 * maximumRadius + 2  : parent.height
282
283         horizontalStep: 1.0 / parent.width
284         verticalStep: 0.0
285
286         source: sourceProxy.output
287         deviation: rootItem.deviation
288         radius: rootItem.radius
289         maximumRadius: rootItem.samples / 2.0
290         transparentBorder: rootItem.transparentBorder
291     }
292 }