Permalink
Browse files

Basic gaussian blur filter, performance can be further improved in th…

…e future
  • Loading branch information...
1 parent f3b5981 commit 67ba92f13892deb7c9e5f58ff1ad61a6ff58926a @cezarsa cezarsa committed Mar 11, 2014
Showing with 50 additions and 5 deletions.
  1. +1 −0 thumbor/config.py
  2. +2 −5 thumbor/ext/filters/_convolution.c
  3. +46 −0 thumbor/filters/blur.py
  4. +1 −0 vows/config_vows.py
View
@@ -204,6 +204,7 @@
'thumbor.filters.format',
'thumbor.filters.max_bytes',
'thumbor.filters.convolution',
+ 'thumbor.filters.blur',
],
'List of filters that thumbor will allow to be used in generated images. All of them must be ' +
'full names of python modules (python must be able to import it)', 'Filters')
@@ -79,12 +79,9 @@ _convolution_apply(PyObject *self, PyObject *args)
for (kernel_x = 0; kernel_x < columns_count; ++kernel_x) {
for (kernel_y = 0; kernel_y < rows_count; ++kernel_y) {
- int kernel_idx = (kernel_y * columns_count) + kernel_x,
- pos_x = kernel_x - mid_x + img_x,
+ int pos_x = kernel_x - mid_x + img_x,
pos_y = kernel_y - mid_y + img_y;
- double kernel_value = kernel[kernel_idx];
-
if (pos_x < 0) {
pos_x = 0;
}
@@ -99,7 +96,7 @@ _convolution_apply(PyObject *self, PyObject *args)
}
int tmp_idx = (pos_y * width_bytes_count) + (pos_x * num_bytes);
-
+ double kernel_value = kernel[(kernel_y * columns_count) + kernel_x];
sum_r += copy_buffer[tmp_idx + r_idx] * kernel_value;
sum_g += copy_buffer[tmp_idx + g_idx] * kernel_value;
sum_b += copy_buffer[tmp_idx + b_idx] * kernel_value;
@@ -0,0 +1,46 @@
+# -*- coding: utf-8 -*-
+
+# thumbor imaging service
+# https://github.com/globocom/thumbor/wiki
+
+# Licensed under the MIT license:
+# http://www.opensource.org/licenses/mit-license
+# Copyright (c) 2011 globo.com timehome@corp.globo.com
+
+import math
+
+from thumbor.filters import BaseFilter, filter_method
+from thumbor.ext.filters import _convolution
+
+MAX_RADIUS = 150
+
+
+class Filter(BaseFilter):
+ """
+ Usage: /filters:blur(<radius> [, <sigma>])
+ Examples of use:
+ /filters:blur(1)/
+ /filters:blur(4)/
+ /filters:blur(4, 2)/
+ """
+
+ def generate_1d_matrix(self, sigma, radius):
+ matrix_size = (radius * 2) + 1
+ matrix = []
+ two_sigma_squared = float(2 * sigma * sigma)
+ for x in xrange(matrix_size):
+ adj_x = x - radius
+ exp = math.e ** -(((adj_x * adj_x)) / two_sigma_squared)
+ matrix.append(exp / math.sqrt(two_sigma_squared * math.pi))
+ return tuple(matrix), matrix_size
+
+ @filter_method(BaseFilter.PositiveNumber, BaseFilter.DecimalNumber)
+ def blur(self, radius, sigma=0):
+ if sigma == 0:
+ sigma = radius
+ if radius > MAX_RADIUS:
+ raise RuntimeError("Radius too large, maximum allowed value is %d" % MAX_RADIUS)
+ matrix, matrix_size = self.generate_1d_matrix(sigma, radius)
+ imgdata = _convolution.apply(self.engine.get_image_mode(), self.engine.get_image_data(), self.engine.size[0], self.engine.size[1], matrix, matrix_size, True)
+ imgdata = _convolution.apply(self.engine.get_image_mode(), imgdata, self.engine.size[0], self.engine.size[1], matrix, 1, True)
+ self.engine.set_image_data(imgdata)
View
@@ -55,6 +55,7 @@
'thumbor.filters.format',
'thumbor.filters.max_bytes',
'thumbor.filters.convolution',
+ 'thumbor.filters.blur',
])
)

0 comments on commit 67ba92f

Please sign in to comment.