http://www.youtube.com/watch?v=M5nRy8Jimvk
------------------------------------
-- Generates a plasma image --------
-- and apply some filters ----------
------------------------------------
function setup()
iparameter("resolution", 1, 2, 1)
parameter("brightness", -255, 255, 0)
parameter("contrast", -100, 100, 0)
iparameter("effect", 0, 5, 0)
print("Touch the screen to generate a new image")
rnd = math.random --I like short names ;-)
contrastLookUpTable = {} --Well, sometimes :-(
palette = {}
generatePalette()
end
function draw()
background(0, 0, 0, 255)
if(oldRes ~= resolution) then
generatePlasma()
oldRes = resolution
end
filterImage(buffer, filterBuffer, brightness, contrast, bw) --Apply filters
sprite(filterBuffer, WIDTH * 0.5,HEIGHT * 0.5, WIDTH, HEIGHT) --Show result
sprite(buffer, 100, 100, 200, 200) --Show thumbnail with non filtered image
end
function touched(touch)
if (CurrentTouch.state == BEGAN) then generatePlasma() end
end
------------------------------------
-- Filters Code --------------------
------------------------------------
function makeContrastLookUpTable(contrast)
contrast = ((100 + contrast) / 100) ^ 2
for n = 0, 255 do
local v = n / 255
v = v - .5
v = v * contrast
v = v + .5
v = v * 255
contrastLookUpTable[n] = v
end
end
function filterImage(orig, dest, brightness, contrast, bw)
local newColor
makeContrastLookUpTable(contrast)
for x = 1, orig.width do
for y = 1, orig.height do
local r, g, b = orig:get(x, y)
--For each color component apply contrast and brightness, then clamp(0, 255)
r = contrastLookUpTable[r] + brightness
if(r < 0) then r = 0 end
if(r > 255) then r = 255 end
g = contrastLookUpTable[g] + brightness
if(g < 0) then g = 0 end
if(g > 255) then g = 255 end
b = contrastLookUpTable[b] + brightness
if(b < 0) then b = 0 end
if(b > 255) then b = 255 end
if (effect == 0) then
newColor = color(r, g, b)
elseif (effect == 1) then --Gray scale
local c = r * .299 + g * .587 + b * .114
newColor = color(c, c, c)
elseif (effect == 2) then --Negative
newColor = color(255 - r, 255 - g, 255 - b)
elseif (effect == 3) then --Components shift 1
newColor = color(b, r, g)
elseif (effect == 4) then --Components shift 2
newColor = color(g, b, r)
elseif (effect == 5) then --Components shift 3
newColor = color(g, r, b)
end
dest:set(x, y, newColor) --Plot the result
end
end
end
------------------------------------
-- Plasma Generator Code -----------
------------------------------------
function generatePalette()
local r, g, b
local c = 0
local inc = 1 / 400
for e = 0, 400 do
if (c < 0.5) then r = c * 2
else r = (1 - c) * 2 end
if (c >= 0.3 and c < 0.8) then g = (c - 0.3) * 2
elseif (c < 0.3) then g = (0.3 - c) * 2
else g = (1.3 - c) * 2 end
if (c >= 0.5) then b = (c - 0.5) * 2
else b = (0.5 - c) * 2 end
palette[e] = color(r * 255, g * 255, b * 255)
c = c + inc
end
end
function generatePlasma()
size = 64 * resolution --Only powers of 2, otherwise we get gaps
buffer = image(size, size)
filterBuffer = image(size, size)
--Start calculating with 4 random corners
divideGrid (dest, 0, 0, size, rnd(), rnd(), rnd(), rnd())
end
function divideGrid(dest, x, y, lenght, c1, c2, c3, c4)
local newLenght = lenght / 2
if (lenght < 2) then --Keep calculating until size is less than 2
buffer:set(x + 1, y + 1, palette[math.floor((c1 + c2 + c3 + c4) * 100)]) --Plot the point
return end
--Calculate the average of the 4 corners and add a random displacement
local middle = (c1 + c2 + c3 + c4) / 4 + (rnd() - 0.5) * newLenght * 3 / size
--Calculate new edges
local edge1 = (c1 + c2) / 2
local edge2 = (c2 + c3) / 2
local edge3 = (c3 + c4) / 2
local edge4 = (c4 + c1) / 2
--Clamp middle between 0 and 1
if (middle < 0) then middle = 0
elseif (middle > 1) then middle = 1 end
--Recursevely call this function for each one of the 4 new rectangles
divideGrid(dest, x, y, newLenght, c1, edge1, middle, edge4)
divideGrid(dest, x + newLenght, y, newLenght, edge1, c2, edge2, middle)
divideGrid(dest, x + newLenght, y + newLenght, newLenght, middle, edge2, c3, edge3)
divideGrid(dest, x, y + newLenght, newLenght, edge4, middle, edge3, c4)
end