Transparency and imageData:paste ?

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
Post Reply
Germanunkol
Party member
Posts: 712
Joined: Fri Jun 22, 2012 4:54 pm
Contact:

Transparency and imageData:paste ?

Post by Germanunkol »

I need to paste imageData 1 onto another imageData 2, where imageData 1 has transparent parts. Using imageDate2:paste(...) it will replace the part of the image entirely. Instead, I want it to overlay the two (I want it to look the way it looks when using love.graphics.draw() over another love.graphics.draw() call).

I don't want to use Canvases.

So I coded my own function transparentPaste which uses getPixel and setPixel to combine the two:
Simplified, this is what it does for every pixel that overlaps:

Code: Select all

rDest,gDest,bDest,aDest = imgDataDest:getPixel(x,y)
rSource,gSource,bSource,aSource = imgDataSource:getPixel(x-posX,y-posY)
if aSource > 0 then
	rSource,gSource,bSource,aSource = rSource/255,gSource/255,bSource/255,aSource/255
	rDest,gDest,bDest,aDest = rDest/255,gDest/255,bDest/255,aDest/255
	a = aSource + aDest*(1-aSource)
	if a > 0 then
		r = (rSource*aSource+rDest*aDest*(1-aSource))/a
		g = (gSource*aSource+gDest*aDest*(1-aSource))/a
		b = (bSource*aSource+bDest*aDest*(1-aSource))/a
	else
		r,g,b = 0,0,0
	end
			
	r,g,b,a = r*255,g*255,b*255,a*255
	imgDataDest:setPixel(x, y, r, g, b, a)
end
However, this is extremely slow.

Any ideas for a better method without canvases?
Why are programs like the GIMP so fast when doing pretty much exactly the same thing (for example when merging two layers)...
trAInsported - Write AI to control your trains
Bandana (Dev blog) - Platformer featuring an awesome little ninja by Micha and me
GridCars - Our jam entry for LD31
Germanunkol.de
User avatar
Xgoff
Party member
Posts: 211
Joined: Fri Nov 19, 2010 4:20 am

Re: Transparency and imageData:paste ?

Post by Xgoff »

Germanunkol wrote:I need to paste imageData 1 onto another imageData 2, where imageData 1 has transparent parts. Using imageDate2:paste(...) it will replace the part of the image entirely. Instead, I want it to overlay the two (I want it to look the way it looks when using love.graphics.draw() over another love.graphics.draw() call).

I don't want to use Canvases.

So I coded my own function transparentPaste which uses getPixel and setPixel to combine the two:
Simplified, this is what it does for every pixel that overlaps:

Code: Select all

rDest,gDest,bDest,aDest = imgDataDest:getPixel(x,y)
rSource,gSource,bSource,aSource = imgDataSource:getPixel(x-posX,y-posY)
if aSource > 0 then
	rSource,gSource,bSource,aSource = rSource/255,gSource/255,bSource/255,aSource/255
	rDest,gDest,bDest,aDest = rDest/255,gDest/255,bDest/255,aDest/255
	a = aSource + aDest*(1-aSource)
	if a > 0 then
		r = (rSource*aSource+rDest*aDest*(1-aSource))/a
		g = (gSource*aSource+gDest*aDest*(1-aSource))/a
		b = (bSource*aSource+bDest*aDest*(1-aSource))/a
	else
		r,g,b = 0,0,0
	end
			
	r,g,b,a = r*255,g*255,b*255,a*255
	imgDataDest:setPixel(x, y, r, g, b, a)
end
However, this is extremely slow.

Any ideas for a better method without canvases?
Why are programs like the GIMP so fast when doing pretty much exactly the same thing (for example when merging two layers)...
you can attempt mapPixel instead, which might be faster but then again it might not. unfortunately, without canvases, this is really the only way to do it

image editing programs are typically written in C or C++ which by themselves are much faster than lua (luajit could also do this quickly, but not with this style of api). compilers might even be able to use specific optimizations like SIMD which would allow them to perform the same operation on several pixel values at once. additionally, the set/getPixel method love uses is particularly slow since it involves jumping back and forth between C and lua, which is expensive itself.

if love allowed getting/setting pixels via a table rather than individually, these types of operations might actually be somewhat cheap, at least compared to the current method
Germanunkol
Party member
Posts: 712
Joined: Fri Jun 22, 2012 4:54 pm
Contact:

Re: Transparency and imageData:paste ?

Post by Germanunkol »

I know C-Style Languages are much faster, I just didn't think it was such a large difference.

I doubt mapPixel will be faster -> it will call the function for every pixel, after all, which my function avoids (I did not post this part, but basically, I add lots of smaller map elements - trees, houses, bushes - to a larger image file (the map). So the pasted image is usually much smaller than the large image, and mapPixel would generate way more function calls than needed...?

However, I might try it... maybe I'm wrong and the internal implementation of mapPixel really is much faster than the set/get functions.

Thanks for your reply!
trAInsported - Write AI to control your trains
Bandana (Dev blog) - Platformer featuring an awesome little ninja by Micha and me
GridCars - Our jam entry for LD31
Germanunkol.de
Post Reply

Who is online

Users browsing this forum: Google [Bot], Roland Chastain and 210 guests