[recipes/image-download: 5/10] Add pixbuf blurring code
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [recipes/image-download: 5/10] Add pixbuf blurring code
- Date: Mon, 6 Mar 2017 00:34:06 +0000 (UTC)
commit 29dbc7158e9689542ab5b6ab4361e66edf9bc6ed
Author: Matthias Clasen <mclasen redhat com>
Date: Fri Mar 3 21:59:09 2017 -0500
Add pixbuf blurring code
This is borrowed from libappstream-glib, and will
be used for a similar purpose: Show a blurred version
of a thumbnail when downloading images from the net.
src/gr-utils.c | 133 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
src/gr-utils.h | 4 ++
2 files changed, 137 insertions(+), 0 deletions(-)
---
diff --git a/src/gr-utils.c b/src/gr-utils.c
index 71dfa95..b32fd7f 100644
--- a/src/gr-utils.c
+++ b/src/gr-utils.c
@@ -692,3 +692,136 @@ remove_image (const char *path)
g_print ("Not removing image %s", path);
}
}
+
+/* blur code borrowed from libappstream-glib */
+static void
+pixbuf_blur_private (GdkPixbuf *src, GdkPixbuf *dest, gint radius, guchar *div_kernel_size)
+{
+ gint width, height, src_rowstride, dest_rowstride, n_channels;
+ guchar *p_src, *p_dest, *c1, *c2;
+ gint x, y, i, i1, i2, width_minus_1, height_minus_1, radius_plus_1;
+ gint r, g, b, a;
+ guchar *p_dest_row, *p_dest_col;
+
+ width = gdk_pixbuf_get_width (src);
+ height = gdk_pixbuf_get_height (src);
+ n_channels = gdk_pixbuf_get_n_channels (src);
+ radius_plus_1 = radius + 1;
+
+ /* horizontal blur */
+ p_src = gdk_pixbuf_get_pixels (src);
+ p_dest = gdk_pixbuf_get_pixels (dest);
+ src_rowstride = gdk_pixbuf_get_rowstride (src);
+ dest_rowstride = gdk_pixbuf_get_rowstride (dest);
+ width_minus_1 = width - 1;
+ for (y = 0; y < height; y++) {
+
+ /* calc the initial sums of the kernel */
+ r = g = b = a = 0;
+ for (i = -radius; i <= radius; i++) {
+ c1 = p_src + (CLAMP (i, 0, width_minus_1) * n_channels);
+ r += c1[0];
+ g += c1[1];
+ b += c1[2];
+ }
+
+ p_dest_row = p_dest;
+ for (x = 0; x < width; x++) {
+ /* set as the mean of the kernel */
+ p_dest_row[0] = div_kernel_size[r];
+ p_dest_row[1] = div_kernel_size[g];
+ p_dest_row[2] = div_kernel_size[b];
+ p_dest_row += n_channels;
+
+ /* the pixel to add to the kernel */
+ i1 = x + radius_plus_1;
+ if (i1 > width_minus_1)
+ i1 = width_minus_1;
+ c1 = p_src + (i1 * n_channels);
+
+ /* the pixel to remove from the kernel */
+ i2 = x - radius;
+ if (i2 < 0)
+ i2 = 0;
+ c2 = p_src + (i2 * n_channels);
+
+ /* calc the new sums of the kernel */
+ r += c1[0] - c2[0];
+ g += c1[1] - c2[1];
+ b += c1[2] - c2[2];
+ }
+
+ p_src += src_rowstride;
+ p_dest += dest_rowstride;
+ }
+
+ /* vertical blur */
+ p_src = gdk_pixbuf_get_pixels (dest);
+ p_dest = gdk_pixbuf_get_pixels (src);
+ src_rowstride = gdk_pixbuf_get_rowstride (dest);
+ dest_rowstride = gdk_pixbuf_get_rowstride (src);
+ height_minus_1 = height - 1;
+ for (x = 0; x < width; x++) {
+
+ /* calc the initial sums of the kernel */
+ r = g = b = a = 0;
+ for (i = -radius; i <= radius; i++) {
+ c1 = p_src + (CLAMP (i, 0, height_minus_1) * src_rowstride);
+ r += c1[0];
+ g += c1[1];
+ b += c1[2];
+ }
+
+ p_dest_col = p_dest;
+ for (y = 0; y < height; y++) {
+ /* set as the mean of the kernel */
+
+ p_dest_col[0] = div_kernel_size[r];
+ p_dest_col[1] = div_kernel_size[g];
+ p_dest_col[2] = div_kernel_size[b];
+ p_dest_col += dest_rowstride;
+
+ /* the pixel to add to the kernel */
+ i1 = y + radius_plus_1;
+ if (i1 > height_minus_1)
+ i1 = height_minus_1;
+ c1 = p_src + (i1 * src_rowstride);
+
+ /* the pixel to remove from the kernel */
+ i2 = y - radius;
+ if (i2 < 0)
+ i2 = 0;
+ c2 = p_src + (i2 * src_rowstride);
+ /* calc the new sums of the kernel */
+ r += c1[0] - c2[0];
+ g += c1[1] - c2[1];
+ b += c1[2] - c2[2];
+ }
+
+ p_src += n_channels;
+ p_dest += n_channels;
+ }
+}
+
+void
+pixbuf_blur (GdkPixbuf *src, gint radius, gint iterations)
+{
+ gint kernel_size;
+ gint i;
+ g_autofree guchar *div_kernel_size = NULL;
+ g_autoptr(GdkPixbuf) tmp = NULL;
+
+ tmp = gdk_pixbuf_new (gdk_pixbuf_get_colorspace (src),
+ gdk_pixbuf_get_has_alpha (src),
+ gdk_pixbuf_get_bits_per_sample (src),
+ gdk_pixbuf_get_width (src),
+ gdk_pixbuf_get_height (src));
+ kernel_size = 2 * radius + 1;
+ div_kernel_size = g_new (guchar, 256 * kernel_size);
+ for (i = 0; i < 256 * kernel_size; i++)
+ div_kernel_size[i] = (guchar) (i / kernel_size);
+
+ while (iterations-- > 0)
+ pixbuf_blur_private (src, tmp, radius, div_kernel_size);
+}
+
diff --git a/src/gr-utils.h b/src/gr-utils.h
index eea9ac2..14632f4 100644
--- a/src/gr-utils.h
+++ b/src/gr-utils.h
@@ -32,6 +32,10 @@ GdkPixbuf *load_pixbuf_fill_size (const char *path,
int width,
int height);
+void pixbuf_blur (GdkPixbuf *src,
+ int radius,
+ int iterations);
+
const char *get_pkg_data_dir (void);
const char *get_user_data_dir (void);
const char *get_old_user_data_dir (void);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]