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.
|
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)
|
raster.invert(surface)
|
||||||
|
|
||||||
Invert the colour in the given surface.
|
Invert the colour in the given surface.
|
||||||
|
|
|
@ -36,7 +36,7 @@ function render_frame(f, t)
|
||||||
ctx.text_path("OverLua")
|
ctx.text_path("OverLua")
|
||||||
ctx.fill()
|
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)
|
f.overlay_cairo_surface(surf, 200, 50)
|
||||||
end
|
end
|
||||||
|
|
|
@ -3,6 +3,7 @@ function render_frame(f, t)
|
||||||
--raster.gaussian_blur(surf, t)--1+(1-math.cos(t*10))*2)
|
--raster.gaussian_blur(surf, t)--1+(1-math.cos(t*10))*2)
|
||||||
--raster.invert(surf)
|
--raster.invert(surf)
|
||||||
--raster.separable_filter(surf, {-1, 3, -1}, 1)
|
--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)
|
f.overlay_cairo_surface(surf, 0, 0)
|
||||||
end
|
end
|
||||||
|
|
|
@ -477,7 +477,8 @@ struct DirectionalBlurFilter {
|
||||||
res.G() = g;
|
res.G() = g;
|
||||||
res.B() = b;
|
res.B() = b;
|
||||||
return res;
|
return res;
|
||||||
}};
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
static int directional_blur(lua_State *L)
|
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)
|
static int invert_image(lua_State *L)
|
||||||
{
|
{
|
||||||
cairo_surface_t *surf = CheckSurface(L, 1);
|
cairo_surface_t *surf = CheckSurface(L, 1);
|
||||||
|
@ -595,7 +689,8 @@ static int separable_filter(lua_State *L)
|
||||||
// Registration
|
// Registration
|
||||||
|
|
||||||
static luaL_Reg rasterlib[] = {
|
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},
|
{"separable_filter", separable_filter},
|
||||||
{"invert", invert_image},
|
{"invert", invert_image},
|
||||||
{NULL, NULL}
|
{NULL, NULL}
|
||||||
|
|
Loading…
Reference in a new issue