I can has radial blur! *wheeee*
Originally committed to SVN as r1490.
This commit is contained in:
parent
e99d9800c0
commit
4ddc7d5820
4 changed files with 105 additions and 4 deletions
|
@ -157,6 +157,11 @@ Apply a variable strength directional gaussian kernel blur to the image.
|
|||
Also known as motion blur. The angle is given in radians.
|
||||
|
||||
|
||||
raster.radial_blur(surface, cx, cy, sigma)
|
||||
|
||||
Apply a variable strength radial gaussian blur centered on pixel (cx,cy).
|
||||
|
||||
|
||||
raster.invert(surface)
|
||||
|
||||
Invert the colour in the given surface.
|
||||
|
|
|
@ -36,7 +36,7 @@ function render_frame(f, t)
|
|||
ctx.text_path("OverLua")
|
||||
ctx.fill()
|
||||
|
||||
raster.gaussian_blur(surf, (1-math.cos(t*10))*2)
|
||||
raster.directional_blur(surf, t, 5)
|
||||
|
||||
f.overlay_cairo_surface(surf, 200, 50)
|
||||
end
|
||||
|
|
|
@ -3,6 +3,7 @@ function render_frame(f, t)
|
|||
--raster.gaussian_blur(surf, t)--1+(1-math.cos(t*10))*2)
|
||||
--raster.invert(surf)
|
||||
--raster.separable_filter(surf, {-1, 3, -1}, 1)
|
||||
raster.directional_blur(surf, t, t/10)
|
||||
--raster.directional_blur(surf, t, t/10)
|
||||
raster.radial_blur(surf, 200, 200, t/60)
|
||||
f.overlay_cairo_surface(surf, 0, 0)
|
||||
end
|
||||
|
|
|
@ -477,7 +477,8 @@ struct DirectionalBlurFilter {
|
|||
res.G() = g;
|
||||
res.B() = b;
|
||||
return res;
|
||||
}};
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
static int directional_blur(lua_State *L)
|
||||
|
@ -493,6 +494,99 @@ static int directional_blur(lua_State *L)
|
|||
}
|
||||
|
||||
|
||||
struct RadialBlurFilter {
|
||||
GaussianKernel gk;
|
||||
int cx, cy;
|
||||
RadialBlurFilter(int x, int y, double sigma) :
|
||||
gk(sigma), cx(x), cy(y)
|
||||
{
|
||||
}
|
||||
inline PixelFormat::A8 a8(BaseImage<PixelFormat::A8> &src, int x, int y)
|
||||
{
|
||||
if (x == cx && y == cy) return src.Pixel(x, y);
|
||||
double xstep = x-cx, ystep = y-cy, ivlen = 1/sqrt(xstep*xstep+ystep*ystep);
|
||||
xstep *= ivlen; ystep *= ivlen;
|
||||
int divisor = 0;
|
||||
int a = 0;
|
||||
for (int t = 0, i = gk.width/2; i < gk.width; t++, i++) {
|
||||
//PixelFormat::A8 &srcpx = GetPixelBilinear<PixelFormat::A8, EdgeCondition::repeat>(src, x+xstep*t, y+ystep*t);
|
||||
PixelFormat::A8 &srcpx = EdgeCondition::repeat(src, (int)(x+xstep*t), (int)(y+ystep*t));
|
||||
a += srcpx.A() * gk.kernel[i];
|
||||
divisor += gk.kernel[i];
|
||||
}
|
||||
PixelFormat::A8 res;
|
||||
a = a / divisor; if (a < 0) a = 0; if (a > 255) a = 255;
|
||||
res.A() = a;
|
||||
return res;
|
||||
}
|
||||
inline PixelFormat::cairo_rgb24 rgb24(BaseImage<PixelFormat::cairo_rgb24> &src, int x, int y)
|
||||
{
|
||||
if (x == cx && y == cy) return src.Pixel(x, y);
|
||||
double xstep = x-cx, ystep = y-cy, ivlen = 1/sqrt(xstep*xstep+ystep*ystep);
|
||||
xstep *= ivlen; ystep *= ivlen;
|
||||
int divisor = 0;
|
||||
int r = 0, g = 0, b = 0;
|
||||
for (int t = 0, i = gk.width/2; i < gk.width; t++, i++) {
|
||||
//PixelFormat::A8 &srcpx = GetPixelBilinear<PixelFormat::A8, EdgeCondition::repeat>(src, x+xstep*t, y+ystep*t);
|
||||
PixelFormat::cairo_rgb24 &srcpx = EdgeCondition::repeat(src, (int)(x+xstep*t), (int)(y+ystep*t));
|
||||
r += srcpx.R() * gk.kernel[i];
|
||||
g += srcpx.G() * gk.kernel[i];
|
||||
b += srcpx.B() * gk.kernel[i];
|
||||
divisor += gk.kernel[i];
|
||||
}
|
||||
PixelFormat::cairo_rgb24 res;
|
||||
r = r / divisor; if (r < 0) r = 0; if (r > 255) r = 255;
|
||||
g = g / divisor; if (g < 0) g = 0; if (g > 255) g = 255;
|
||||
b = b / divisor; if (b < 0) b = 0; if (b > 255) b = 255;
|
||||
res.R() = r;
|
||||
res.G() = g;
|
||||
res.B() = b;
|
||||
return res;
|
||||
}
|
||||
inline PixelFormat::cairo_argb32 argb32(BaseImage<PixelFormat::cairo_argb32> &src, int x, int y)
|
||||
{
|
||||
if (x == cx && y == cy) return src.Pixel(x, y);
|
||||
double xstep = x-cx, ystep = y-cy, ivlen = 1/sqrt(xstep*xstep+ystep*ystep);
|
||||
xstep *= ivlen; ystep *= ivlen;
|
||||
int divisor = 0;
|
||||
int a = 0, r = 0, g = 0, b = 0;
|
||||
for (int t = 0, i = gk.width/2; i < gk.width; t++, i++) {
|
||||
//PixelFormat::A8 &srcpx = GetPixelBilinear<PixelFormat::A8, EdgeCondition::repeat>(src, x+xstep*t, y+ystep*t);
|
||||
PixelFormat::cairo_argb32 &srcpx = EdgeCondition::repeat(src, (int)(x+xstep*t), (int)(y+ystep*t));
|
||||
a += srcpx.A() * gk.kernel[i];
|
||||
r += srcpx.R() * gk.kernel[i];
|
||||
g += srcpx.G() * gk.kernel[i];
|
||||
b += srcpx.B() * gk.kernel[i];
|
||||
divisor += gk.kernel[i];
|
||||
}
|
||||
PixelFormat::cairo_argb32 res;
|
||||
a = a / divisor; if (a < 0) a = 0; if (a > 255) a = 255;
|
||||
r = r / divisor; if (r < 0) r = 0; if (r > 255) r = 255;
|
||||
g = g / divisor; if (g < 0) g = 0; if (g > 255) g = 255;
|
||||
b = b / divisor; if (b < 0) b = 0; if (b > 255) b = 255;
|
||||
res.A() = a;
|
||||
res.R() = r;
|
||||
res.G() = g;
|
||||
res.B() = b;
|
||||
return res;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
static int radial_blur(lua_State *L)
|
||||
{
|
||||
cairo_surface_t *surf = CheckSurface(L, 1);
|
||||
int x = luaL_checkint(L, 2);
|
||||
int y = luaL_checkint(L, 3);
|
||||
double sigma = luaL_checknumber(L, 4);
|
||||
|
||||
RadialBlurFilter filter(x, y, sigma);
|
||||
ApplyGeneralFilter(L, surf, filter);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int invert_image(lua_State *L)
|
||||
{
|
||||
cairo_surface_t *surf = CheckSurface(L, 1);
|
||||
|
@ -595,7 +689,8 @@ static int separable_filter(lua_State *L)
|
|||
// Registration
|
||||
|
||||
static luaL_Reg rasterlib[] = {
|
||||
{"gaussian_blur", gaussian_blur}, {"box_blur", box_blur}, {"directional_blur", directional_blur},
|
||||
{"gaussian_blur", gaussian_blur}, {"box_blur", box_blur},
|
||||
{"directional_blur", directional_blur}, {"radial_blur", radial_blur},
|
||||
{"separable_filter", separable_filter},
|
||||
{"invert", invert_image},
|
||||
{NULL, NULL}
|
||||
|
|
Loading…
Reference in a new issue