Last active
November 21, 2019 13:09
-
-
Save dionyziz/49696a58d072daebea91f4bdb7183203 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <cstdio> | |
#include <iostream> | |
#include <cairo.h> | |
using namespace std; | |
struct RGBA { | |
int a, r, g, b; | |
}; | |
const int bytes_per_row = 4; | |
const int BLUR = 20; | |
RGBA read_pixel(int w, int h, unsigned char* data, int x, int y) { | |
RGBA ret; | |
int stride = bytes_per_row * w; | |
int a_loc = stride * y + x * bytes_per_row + 0, | |
r_loc = stride * y + x * bytes_per_row + 1, | |
g_loc = stride * y + x * bytes_per_row + 2, | |
b_loc = stride * y + x * bytes_per_row + 3; | |
ret.a = data[a_loc]; | |
ret.r = data[r_loc]; | |
ret.g = data[g_loc]; | |
ret.b = data[b_loc]; | |
return ret; | |
} | |
void write_pixel(int w, int h, unsigned char* data, int x, int y, RGBA pixel) { | |
int stride = bytes_per_row * w; | |
int a_loc = stride * y + x * bytes_per_row + 0, | |
r_loc = stride * y + x * bytes_per_row + 1, | |
g_loc = stride * y + x * bytes_per_row + 2, | |
b_loc = stride * y + x * bytes_per_row + 3; | |
data[a_loc] = pixel.a; | |
data[r_loc] = pixel.r; | |
data[g_loc] = pixel.g; | |
data[b_loc] = pixel.b; | |
} | |
void add_pixel(RGBA &dest, RGBA src) { | |
dest.a += src.a; | |
dest.r += src.r; | |
dest.g += src.g; | |
dest.b += src.b; | |
} | |
void scale_pixel(RGBA &pixel, float lambda) { | |
pixel.a *= lambda; | |
pixel.r *= lambda; | |
pixel.g *= lambda; | |
pixel.b *= lambda; | |
} | |
int main() { | |
cairo_surface_t* source_surface = cairo_image_surface_create_from_png("dionyziz.png"); | |
cairo_format_t source_fmt = cairo_image_surface_get_format(source_surface); | |
int w = cairo_image_surface_get_width(source_surface); | |
int h = cairo_image_surface_get_height(source_surface); | |
int stride = cairo_image_surface_get_stride(source_surface); | |
int bytes_per_row = stride / w; | |
unsigned char* source_data = cairo_image_surface_get_data(source_surface); | |
unsigned char* dest_data = (unsigned char*)malloc(stride * h); | |
int i = 0; | |
for (int y = 0; y < h; ++y) { | |
for (int x = 0; x < w; ++x) { | |
RGBA pixel = (RGBA){0, 0, 0, 0}; | |
int cnt = 0; | |
for (int dx = -BLUR; dx <= BLUR; ++dx) { | |
for (int dy = -BLUR; dy <= BLUR; ++dy) { | |
if (x + dx >= 0 && x + dx < w && y + dy >= 0 && y + dy < h) { | |
RGBA neighbour_pixel = read_pixel(w, h, source_data, x + dx, y + dy); | |
add_pixel(pixel, neighbour_pixel); | |
++cnt; | |
} | |
} | |
} | |
scale_pixel(pixel, 1.0 / cnt); | |
write_pixel(w, h, dest_data, x, y, pixel); | |
} | |
} | |
cout << "Blurred image " << w << "x" << h << " with stride " << stride << endl; | |
cairo_surface_t* dest_surface = cairo_image_surface_create_for_data(dest_data, source_fmt, w, h, stride); | |
cairo_surface_write_to_png(dest_surface, "dionyziz-blurred.png"); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment