94. More than one way to blend images
It’s quite interesting how different people approach the same problem, in this case, how to make one image gradually turn into another.
I’ll start with the solution posted by Jmv38 on the forum.
function setup() data = {alpha = 255} next = 0 end function draw() background(40, 40, 50) fontSize(50) text('touch me',WIDTH/2,HEIGHT/8) scale(4) --draw everything 4x larger from here on tint(255,255,255,data.alpha) --see below sprite('Planet Cute:Character Boy',WIDTH/8,HEIGHT/8) tint(255,255,255,255-data.alpha) sprite('Planet Cute:Character Princess Girl',WIDTH/8,HEIGHT/8) end function touched(touch) if touch.state == BEGAN then tween(1,data,{alpha = next}) --see below next = 255-next end end
There are a few interesting techniques in this code.
scale(4) – this tells Codea to draw everything 4 times larger from here onwards. This is just because the images are rather small.
tint – tint adds a colour shade to an image. The documentation says that if you make the colour white, and make the alpha value less than 255, it makes the image partly transparent. So you’ll see each image is tinted differently
tint(255,255,255,data.alpha) --first image tint(255,255,255,255-data.alpha) --second image
The first image gets an alpha (transparency) value of whatever is in the data.alpha variable, while the other image gets 255-data.alpha. So if data.alpha runs from 0-255 or from 255 to 0, one image will morph into the other.
The most interesting feature is using the tween command as a timer. tween is usually used to produce image animations, eg move an image from a to b in 2 seconds, or bounce between a and b. Here it is being used to change a variable called data.alpha from 255 to 0 over 1 second. It’s worth reading the documentation on tweens. I find them a bit confusing at times, but a bit of practice should fix that. (I will have to do a post on tweens to force myself to learn about them!).
My approach
Now here is the approach I would have taken, using a mesh and one of the built in shaders (fancy graphics utilities), which was written specifically to blend images. If you know meshes and shaders, this is fairly simple. If you don’t know about them, it’s worth trying to learn, because they are very useful for graphics programming. I’ve written lots of posts on shaders, and they aren’t as scary as they seem at first.
function setup() img1=readImage('Planet Cute:Character Pink Girl') --create simple rectangular mesh, with image m=mesh() m:addRect(200,200,img1.width,img1.height) m.texture=img1 --define shader m.shader=shader('Basic:Blend Images') --set second texture for shader to blend into img2=readImage('Planet Cute:Character Princess Girl') m.shader.texture2=img2 --give shader the blend fraction (this will change) m.mixAmount=0 --time taken to blend transitionSeconds=10 --timer will be used to calculate blend fraction timer=nil --disable it initially print('Touch the screen to start the transition') end function draw() background(40, 40, 50) if timer~=nil then --if timer is active.. timer=timer+DeltaTime --add time since last draw --calculate blend fraction based on timer m.shader.mixAmount=math.min(timer,transitionSeconds)/transitionSeconds end m:draw() end function touched(touch) if touch.state == ENDED then timer=0 --start timer end end
Actually, I like Jmv38’s code better, because that tint trick is so cool. I think I prefer to use a normal timer rather than tween, though.