Sorting Filter
So here is a fun effect you can try at home. Take an image, break it up in to small squares (I used 5x5 pixels). For each of these squares, rearrange the pixels in that square so that they are in order of intensity from top left to bottom right. If you do this, you will get a 5x5 tiled pattern which looks ok, but hardly useful. So then if you repeat this process 25 more times, but take the squares from different starting positions each time, then you can get 25 of these tiled patterns where the tile boundaries don't line up at all. Mix all of these images together, and you have what I'm calling a sorting filter.
I didn't actually use intensity, I said that a (r1, g1, b1) preceeds (r2, g2, b2) if (r1r1 + g1g1 + b1b1) < (r2r2 + g2g2 + b2b2). I don't really know what that is called, but everyone likes to square things (I wanted to make strong colours beat medium greys... I don't know why).
So my implementation is super slow because I'm lazy (not because it is a complicated effect that needs to be CPU intensive) but here are two example images:
The actual result is very similar to a normal blur, but the shapes of objects change slightly when you use this method, which makes it a bit cooler.

The C code used to generate this (so you can admire its inefficiency) is: (and one day I'll get around to giving some code that isn't so trivial that it deserves more than public domain (though I decided to include my name in this one, so I suppose I'm getting closer))
// Public domain
// by Andy Owen (http://www.ultra-premium.com/b)
#include <stdio.h>
#include <stdlib.h>
#include "image/image.h"
#define X_RADIUS (15)
#define Y_RADIUS (15)
static void swapPixels(Image img, int x1, int y1, int x2, int y2);
static Image mixImages(int numImages, Image *images);
static void sortArea(Image img, int left, int top, int w, int h);
static int rgbCompare(Rgb a, Rgb b);
int main(int argc, char* argv[]) {
Image img = loadImage(argv[1]);
int width = getWidth(img);
int height = getHeight(img);
Image copies[X_RADIUS * Y_RADIUS];
int c = 0;
for (int offX = 0; offX < X_RADIUS; offX++) {
for (int offY = 0; offY < Y_RADIUS; offY++) {
copies[c] = duplicateImage(img);
for (int y = offX; y < height + offX; y += Y_RADIUS) {
for (int x = offY; x < width + offY; x += X_RADIUS) {
sortArea(copies[c], x, y, X_RADIUS, Y_RADIUS);
}
}
c++;
}
}
Image mix = mixImages(X_RADIUS * Y_RADIUS, copies);
saveImage(mix, "copy.bmp");
destroyImage(mix);
for (int c = 0; c < (X_RADIUS * Y_RADIUS); c++) {
destroyImage(copies[c]);
}
return 0;
}
static Image mixImages(int numImages, Image *images) {
int width = getWidth(images[0]);
int height = getHeight(images[1]);
Image ret = createImage(width, height);
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
Rgb value;
value.red = value.green = value.blue = 0;
for (int i = 0; i < numImages; i++) {
Rgb add = getPixelRgb(images[i], x, y);
value.red += add.red;
value.green += add.green;
value.blue += add.blue;
}
value.red /= numImages;
value.green /= numImages;
value.blue /= numImages;
setPixelRgb(ret, x, y, value);
}
}
return ret;
}
static void sortArea(Image img, int left, int top, int w, int h) {
int imgWidth = getWidth(img);
int imgHeight = getHeight(img);
int sortOrder = 1;
for (int y = top; y < top + h; y++) {
for (int x = left; x < left + w; x++) {
for (int y1 = top; y1 < top + h; y1++) {
for (int x1 = left; x1 < left + w; x1++) {
if (rgbCompare(
getPixelRgb(img, x % imgWidth, y % imgHeight),
getPixelRgb(img, x1 % imgWidth, y1 % imgHeight)) == sortOrder) {
swapPixels(img, x % imgWidth, y % imgHeight,
x1 % imgWidth, y1 % imgHeight);
}
}
}
}
}
}
static int rgbCompare(Rgb a, Rgb b) {
int av2 = a.red * a.red + a.green * a.green + a.blue * a.blue;
int bv2 = b.red * b.red + b.green * b.green + b.blue * b.blue;
if (av2 < bv2) {
return -1;
}
if (av2 > bv2) {
return 1;
}
return 0;
}
static void swapPixels(Image img, int x1, int y1, int x2, int y2) {
Rgb temp = getPixelRgb(img, x1, y1);
setPixelRgb(img, x1, y1, getPixelRgb(img, x2, y2));
setPixelRgb(img, x2, y2, temp);
}
The image library it is using is one of my own. It isn't quite ready to face the world. But you can just substitute your own in, the interface should be simple enough.

RSS
oil painting网络摄像机记录仪温度记录仪产品设计power levelingwow power levelingwow power leveling安检门检针机工业设计embroidery machinessewing machinesair conditioner
power levelingwow powerlevelingwow power levelingworld of warcraft power levelingworld of warcraft powerlevelingworld of warcraft power levelingrunescape moneyrunescape gold