improve blur effect
This commit is contained in:
parent
5c67b05102
commit
6d9f9999ec
2 changed files with 54 additions and 30 deletions
|
|
@ -8,6 +8,10 @@ http://www.newbreedsoftware.com/tuxpaint/
|
||||||
|
|
||||||
|
|
||||||
2004.December.5 (0.9.15)
|
2004.December.5 (0.9.15)
|
||||||
|
* Magic blur effect now gamma-aware, circular, and modifying all points
|
||||||
|
within the brush instead of just 25% of them.
|
||||||
|
Albert Cahalan <albert@users.sf.net>
|
||||||
|
|
||||||
* fixed display corruption in load dialog when saved images are
|
* fixed display corruption in load dialog when saved images are
|
||||||
from a larger display size
|
from a larger display size
|
||||||
Albert Cahalan <albert@users.sf.net>
|
Albert Cahalan <albert@users.sf.net>
|
||||||
|
|
|
||||||
|
|
@ -4063,41 +4063,61 @@ static void blit_magic(int x, int y, int button_down)
|
||||||
|
|
||||||
if (cur_magic == MAGIC_BLUR)
|
if (cur_magic == MAGIC_BLUR)
|
||||||
{
|
{
|
||||||
/* FIXME: Circular "brush?" */
|
double state[32][32][3];
|
||||||
|
unsigned i = 32*32;
|
||||||
|
|
||||||
SDL_LockSurface(canvas);
|
SDL_LockSurface(canvas);
|
||||||
for (yy = y - 16; yy < y + 16; yy = yy + 2)
|
|
||||||
|
while (i--)
|
||||||
{
|
{
|
||||||
for (xx = x - 16; xx < x + 16; xx = xx + 2)
|
int iy = i>>5;
|
||||||
{
|
int ix = i&0x1f;
|
||||||
SDL_GetRGB(getpixel(canvas, clamp(0, xx, canvas->w - 1),
|
// is it not on the circle of radius sqrt(220) at location 16,16?
|
||||||
clamp(0, yy - 1, canvas->h - 1)),
|
if ( (ix-16)*(ix-16) + (iy-16)*(iy-16) > 220)
|
||||||
canvas->format,
|
continue;
|
||||||
&r1, &g1, &b1);
|
// it is on the circle, so grab it
|
||||||
|
|
||||||
SDL_GetRGB(getpixel(canvas, clamp(0, xx - 1, canvas->w - 1),
|
SDL_GetRGB(getpixel(canvas, x+ix-16, y+iy-16), last->format, &r, &g, &b);
|
||||||
clamp(0, yy, canvas->h - 1)),
|
state[ix][iy][0] = sRGB_to_linear_table[r];
|
||||||
canvas->format,
|
state[ix][iy][1] = sRGB_to_linear_table[g];
|
||||||
&r2, &g2, &b2);
|
state[ix][iy][2] = sRGB_to_linear_table[b];
|
||||||
|
|
||||||
SDL_GetRGB(getpixel(canvas, clamp(0, xx + 1, canvas->w - 1),
|
|
||||||
clamp(0, yy, canvas->h - 1)),
|
|
||||||
canvas->format,
|
|
||||||
&r3, &g3, &b3);
|
|
||||||
|
|
||||||
SDL_GetRGB(getpixel(canvas, clamp(0, xx, canvas->w - 1),
|
|
||||||
clamp(0, yy + 1, canvas->h - 1)),
|
|
||||||
canvas->format,
|
|
||||||
&r4, &g4, &b4);
|
|
||||||
|
|
||||||
|
|
||||||
r = (r1 + r2 + r3 + r4) >> 2;
|
|
||||||
g = (g1 + g2 + g3 + g4) >> 2;
|
|
||||||
b = (b1 + b2 + b3 + b4) >> 2;
|
|
||||||
|
|
||||||
putpixel(canvas, xx, yy,
|
|
||||||
SDL_MapRGB(canvas->format, r, g, b));
|
|
||||||
}
|
}
|
||||||
|
i = 32*32;
|
||||||
|
while (i--)
|
||||||
|
{
|
||||||
|
double lr, lg, lb; // linear red,green,blue
|
||||||
|
double weight;
|
||||||
|
int iy = i>>5;
|
||||||
|
int ix = i&0x1f;
|
||||||
|
int r2 = (ix-16)*(ix-16) + (iy-16)*(iy-16); // radius squared
|
||||||
|
|
||||||
|
// is it not on the circle of radius sqrt(140) at location 16,16?
|
||||||
|
if ( r2 > 140)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// It is on the circle, but how strongly will it be affected?
|
||||||
|
// This is lame; we should use something like a gaussian or cosine
|
||||||
|
// via a lookup table. (inverted, because this is the center weight)
|
||||||
|
weight = r2/16.0+3.0;
|
||||||
|
|
||||||
|
// Sampling more points would be good too, though it'd be slower.
|
||||||
|
|
||||||
|
lr = state[ix][iy-1][0]
|
||||||
|
+ state[ix-1][iy][0] + state[ix][iy ][0]*weight + state[ix+1][iy][0]
|
||||||
|
+ state[ix][iy+1][0];
|
||||||
|
|
||||||
|
lg = state[ix][iy-1][1]
|
||||||
|
+ state[ix-1][iy][1] + state[ix][iy ][1]*weight + state[ix+1][iy][1]
|
||||||
|
+ state[ix][iy+1][1];
|
||||||
|
|
||||||
|
lb = state[ix][iy-1][2]
|
||||||
|
+ state[ix-1][iy][2] + state[ix][iy ][2]*weight + state[ix+1][iy][2]
|
||||||
|
+ state[ix][iy+1][2];
|
||||||
|
|
||||||
|
lr /= weight+4.0;
|
||||||
|
lg /= weight+4.0;
|
||||||
|
lb /= weight+4.0;
|
||||||
|
putpixel(canvas, x+ix-16, y+iy-16, SDL_MapRGB(canvas->format, linear_to_sRGB(lr), linear_to_sRGB(lg), linear_to_sRGB(lb)));
|
||||||
}
|
}
|
||||||
SDL_UnlockSurface(canvas);
|
SDL_UnlockSurface(canvas);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue