
I was talking to Snae in #gosu and he wanted to scale a texture (during a splice) and also to blur. Unfortunately TexPlay does not natively support this functionality. However, we can build it in easily enough and even give it a pretty interface using the macro functionality.
This is the API we came up with:
To scale an image (during a splice):
img1.splice_and_scale img2, x, y, :factor => 2
* The above will splice a scaled version of img2 into img1
* Note x and y coords can be scaled separately using :factor_x and :factor_y.
* Valid scale factors include all positive integers and fractional values. Including values < 1 for minimization.
To blur an image:
img1.blur :blur_radius => 4
* Set the blur radius (degree of blurriness) using the :blur_radius parameter
* Can also specify a region to blur using the :region parameter, a la the TexPlay#each iterator
* Note: blurring is SLOW, so do not use for real time stuff. Just use for pre-rendering images
* A much faster version of this blurring algorithm will be available soon
Here are the implementations of the above functions:
# Scaling
# uses nearest-neighbour
TexPlay::create_macro(:splice_and_scale) do |img, cx, cy, *options|
options = options.first ? options.first : {}
options = {
:color_control => proc do |c1, c2, x, y|
factor = options[:factor] || 1
factor_x = options[:factor_x] || factor
factor_y = options[:factor_y] || factor
x = factor_x * (x - cx) + cx
y = factor_y * (y - cy) + cy
rect x, y, x + factor_x, y + factor_y, :color => c2, :fill => true
:none
end
}.merge!(options)
splice img, cx, cy, options
self
end
# Blurring
# Code by Snae
TexPlay::create_macro(:blur) do |*options|
options = options.first ? options.first : {}
radius = options[:blur_radius] || 1
self.each(options) { |c,x,y|
total = [0, 0, 0, 0]
for ky in (-radius..radius)
for kx in (-radius..radius)
v = get_pixel(x + kx, y + ky);
if v
total[0] += v[0]
total[1] += v[1]
total[2] += v[2]
total[3] += v[3]
end
end
end
c[0] = total[0] / (radius * 2 + 1) ** 2
c[1] = total[1] / (radius * 2 + 1) ** 2
c[2] = total[2] / (radius * 2 + 1) ** 2
c[3] = total[3] / (radius * 2 + 1) ** 2
}
self
end
attached are some examples of scaling / blurring images. Note that the blurring example only blurs a portion of the image (the area where the people are walking)