Code archives/Graphics/Image Blending Functions

This code has been declared by its author to be Public Domain code.

Download source code

Image Blending Functions by Krischan
(Posted 18 years ago)
A quick collection of Image Blending Functions like these in Photoshop. Very usable for blending heightmaps together to produce completely new terrains: I am not sure if all functions are translated correctly - feel free to comment, post fixes or simplify the code.

19 Blending Functions available: Average, Multiply, Screen, Darken, Lighten, Difference, Negation, Exclusion, Overlay, HardLight, SoftLight, ColorDodge, InverseColorDodge, SoftColorDodge, ColorBurn, InverseColorBurn, SoftColorBurn, Reflect, Glow

To see it in a working demo take a look at my Realtime Procedural Planet Generator: http://www.blitzbasic.com/codearcs/codearcs.php?code=2416
; Image Blend Modes
; by Krischan webmaster(at)jaas.de
;
; Idea Credit: http://www.pegtop.net/delphi/articles/blendmodes/intro.htm
; get the two images there or use your own (need to have the same size for this demo)

AppTitle "Image Blend Functions"


Graphics 400,300,32,2

image1=LoadImage("baseimage.jpg")
image2=LoadImage("blendimage.jpg")
image3=CreateImage(200,150)

ib1=ImageBuffer(image1)
ib2=ImageBuffer(image2)
ib3=ImageBuffer(image3)

start=MilliSecs()

LockBuffer ib1
LockBuffer ib2
LockBuffer ib3

For x=0 To 199
	
	For y=0 To 149
		
		rgb1=ReadPixelFast(x,y,ib1)
		rgb2=ReadPixelFast(x,y,ib2)
		
		r1%=(rgb1 And $ff0000)/$10000
		g1%=(rgb1 And $ff00)/$100
		b1%=(rgb1 And $ff)
		
		r2%=(rgb2 And $ff0000)/$10000
		g2%=(rgb2 And $ff00)/$100
		b2%=(rgb2 And $ff)
		
		r3=SoftLight(r1,r2)
		g3=SoftLight(g1,g2)
		b3=SoftLight(b1,b2)
		
		rgb3=r3*$10000+g3*$100+b3
		
		WritePixelFast x,y,rgb3,ib3
		
	Next
	
Next

UnlockBuffer ib3
UnlockBuffer ib2
UnlockBuffer ib1

ms=MilliSecs()-start

While Not KeyHit(1)
	
	DrawImage image1,0,0
	DrawImage image2,200,0
	DrawImage image3,100,150
	
	Text 0,0,ms+"ms"
	
	Flip
	
Wend

End

Function Average(a%,b%)
	
	Return (a+b) Shr 1
	
End Function

Function Multiply(a%,b%)
	
	Return (a*b) Shr 8
	
End Function

Function Screen(a%,b%)
	
	Return 255-((255-a)*(255-b) Shr 8)
	
End Function

Function Darken(a%,b%)
	
	If a<b Then Return a Else Return b
	
End Function

Function Lighten(a%,b%)
	
	If a>b Then Return a Else Return b
	
End Function

Function Difference(a%,b%)
	
	Return Abs(a-b)
	
End Function

Function Negation(a%,b%)
	
	Return 255-Abs(255-a-b)
	
End Function

Function Exclusion(a%,b%)
	
	Return a+b-(a*b Shr 7)
	
End Function

Function Overlay(a%,b%)
	
	If a<128 Then Return (a*b) Shr 7 Else Return 255-((255-a)*(255-b) Shr 7)
	
End Function

Function HardLight(a%,b%)
	
	If b<128 Then Return (a*b) Shr 7 Else Return 255-((255-b)*(255-a) Shr 7)
	
End Function

Function SoftLight(a%,b%)
	
	Local c%=a*b Shr 8
	Return (c+a*(255-((255-a)*(255-b) Shr 8)-c) Shr 8)
	
End Function

Function ColorDodge(a%,b%)
	
	If b=255 Then
		Return 255
	Else
		Local c%=Floor((a Shl 8)/(255-b))
		If c>255 Then Return 255 Else Return c
	EndIf
	
End Function

Function InverseColorDodge(a%,b%)
	
	If a=255 Then
		Return 255
	Else
		Local c%=Floor((b Shl 8)/(255-a))
		If c>255 Then Return 255 Else Return c
	EndIf
	
End Function

Function SoftColorDodge(a%,b%)
	
	Local c%
	
	If a+b<256 Then
		If b=255 Then
			Return 255
		Else
			c=Floor((a Shl 7)/(255-b))
			If c>255 Then Return 255 Else Return c
		EndIf
	Else
		c=255-Floor((((255-b) Shl 7)/a))
		If c<0 Then Return 0 Else Return c
	EndIf
	
End Function

Function ColorBurn(a%,b%)
	
	If b=0 Then
		Return 0
	Else
		Local c%=255-Floor(((255-a) Shl 8)/b)
		If c<0 Then Return 0 Else Return c
	EndIf
	
End Function

Function InverseColorBurn(a%,b%)
	
	If a=0 Then
		Return 0
	Else
		Local c%=255-Floor(((255-b) Shl 8)/a)
		If c<0 Then Return 0 Else Return c
	EndIf
	
End Function

Function SoftColorBurn(a%,b%)
	
	Local c%
	
	If a+b<256 Then
		If a=255 Then
			Return 255
		Else
			c=Floor((b Shl 7)/(255-a))
			If c>255 Then Return 255 Else Return c
		EndIf
	Else
		c=255-Floor(((255-a) Shl 7)/b)
		If c<0 Then Return 0 Else Return c
	EndIf
	
End Function

Function Reflect(a%,b%)
	
	If b = 255 Then
		Return 255
	Else
		Local c%=Floor(a*a/(255-b))
		If c>255 Then Return 255 Else Return c
	EndIf
	
End Function

Function Glow(a%,b%)
	
	If a=255 Then
		Return 255
	Else
		Local c%=Floor(b*b/(255-a))
		If c>255 Then Return 255 Else Return c
	EndIf
	
End Function

Comments

Plash
(Posted 18 years ago)
BlitzMax version:
SuperStrict

Framework brl.blitz

Import brl.glmax2d
Import brl.jpgloader

AppTitle = "Image Blend Functions"
SetGraphicsDriver(GLMax2DDriver())
Graphics(400, 300, 0)

Local start:Int, ms:Int
Local image1:TImage, image2:TImage, image3:TImage
Local pix1:TPixmap, pix2:TPixmap, pix3:TPixmap

image1 = LoadImage("baseimage.jpg")
image2 = LoadImage("blendimage.jpg")
image3 = CreateImage(200, 150)

pix1 = image1.Lock(0, True, True)
pix2 = image2.Lock(0, True, True)
pix3 = image3.Lock(0, True, True)

Local x:Int, y:Int
Local argb1:TARGB, argb2:TARGB
argb1 = New TARGB
argb2 = New TARGB

start = MilliSecs()
For x = 0 To image3.width - 1
	
	For y = 0 To image3.height - 1
		
		argb1.Set(pix1.ReadPixel(x, y))
		argb2.Set(pix2.ReadPixel(x, y))
		
		' Force full alpha
		pix3.WritePixel(x, y, TARGB.ConvToARGB(SoftLight(argb1.r, argb2.r), SoftLight(argb1.g, argb2.g), SoftLight(argb1.b, argb2.b), 255))
		
	Next
	
Next
ms = MilliSecs() - start

While KeyHit(KEY_ESCAPE) = False
	
	Cls()
	
	DrawImage(image1, 0.0, 0.0)
	DrawImage(image2, 200.0, 0.0)
	DrawImage(image3, 100.0, 150.0)
	
	DrawText(ms + "ms", 0.0, 0.0)
	
	Flip()
	
Wend


Type TARGB
	
	Field r:Int, g:Int, b:Int, a:Int
	
		Method Set(argb:Int)
			
			r = (argb Shr 16) & $ff
			g = (argb Shr 8) & $ff
			b = (argb & $ff)
			
			a = (argb Shr 24) & $ff
			
		End Method
		
		Method Get:Int()
			
			Return Int(a * $1000000) + Int(r * $10000) + Int(g * $100) + Int(b)
			
		End Method
		
		
		Function ConvToARGB:Int(r:Int, g:Int, b:Int, a:Int)
			
			Return Int(a * $1000000) + Int(r * $10000) + Int(g * $100) + Int(b)
			
		End Function
		
End Type


Function Average:Int(a:Int, b:Int)
	
	Return (a + b) Shr 1
	
End Function

Function Multiply:Int(a:Int, b:Int)
	
	Return (a * b) Shr 8
	
End Function

Function Screen:Int(a:Int, b:Int)
	
	Return 255 - ((255 - a) * (255 - b) Shr 8)
	
End Function

Function Darken:Int(a:Int, b:Int)
	
	If a < b Then Return a Else Return b
	
End Function

Function Lighten:Int(a:Int, b:Int)
	
	If a > b Then Return a Else Return b
	
End Function

Function Difference:Int(a:Int, b:Int)
	
	Return Abs(a - b)
	
End Function

Function Negation:Int(a:Int, b:Int)
	
	Return 255 - Abs(255 - a - b)
	
End Function

Function Exclusion:Int(a:Int, b:Int)
	
	Return a + b - (a * b Shr 7)
	
End Function

Function Overlay:Int(a:Int, b:Int)
	
	If a < 128 Then Return (a * b) Shr 7 Else Return 255 - ((255 - a) * (255 - b) Shr 7)
	
End Function

Function HardLight:Int(a:Int, b:Int)
	
	If b < 128 Then Return (a * b) Shr 7 Else Return 255 - ((255 - b) * (255 - a) Shr 7)
	
End Function

Function SoftLight:Int(a:Int, b:Int)
	Local c:Int
	
	c = a * b Shr 8
	Return (c + a * (255 - ((255 - a) * (255 - b) Shr 8) - c) Shr 8)
	
End Function

Function ColorDodge:Int(a:Int, b:Int)
	
	If b = 255
		
		Return 255
		
	Else
		Local c:Int
		
		c = Floor((a Shl 8) / (255 - b))
		If c > 255 Then Return 255 Else Return c
		
	End If
	
End Function

Function InverseColorDodge:Int(a:Int, b:Int)
	
	If a = 255
		
		Return 255
		
	Else
		Local c:Int
		
		c = Floor((b Shl 8) / (255 - a))
		If c > 255 Then Return 255 Else Return c
		
	End If
	
End Function

Function SoftColorDodge:Int(a:Int, b:Int)
	Local c:Int
	
	If a + b < 256
		
		If b = 255
			
			Return 255
			
		Else
			
			c = Floor((a Shl 7) / (255 - b))
			If c > 255 Then Return 255 Else Return c
			
		End If
		
	Else
		
		c = 255 - Floor((((255 - b) Shl 7) / a))
		If c < 0 Then Return 0 Else Return c
		
	End If
	
End Function

Function ColorBurn:Int(a:Int, b:Int)
	
	If b = 0
		
		Return 0
		
	Else
		
		Local c:Int = 255 - Floor(((255 - a) Shl 8) / b)
		If c < 0 Then Return 0 Else Return c
		
	End If
	
End Function

Function InverseColorBurn:Int(a:Int, b:Int)
	
	If a = 0
		
		Return 0
		
	Else
		Local c:Int
		
		c = 255 - Floor(((255 - b) Shl 8) / a)
		If c < 0 Then Return 0 Else Return c
		
	End If
	
End Function

Function SoftColorBurn:Int(a:Int, b:Int)
	Local c:Int
	
	If a + b < 256
		
		If a = 255
			
			Return 255
			
		Else
			
			c = Floor((b Shl 7) / (255 - a))
			If c > 255 Then Return 255 Else Return c
			
		End If
		
	Else
		
		c = 255 - Floor(((255 - a) Shl 7) / b)
		If c < 0 Then Return 0 Else Return c
		
	End If
	
End Function

Function Reflect:Int(a:Int, b:Int)
	
	If b = 255
		Return 255
	Else
		Local c:Int
		
		c = Floor(a * a / (255 - b))
		If c > 255 Then Return 255 Else Return c
		
	End If
	
End Function

Function Glow:Int(a:Int, b:Int)
	
	If a = 255
		
		Return 255
		
	Else
		Local c:Int
		
		c = Floor(b * b / (255 - a))
		If c > 255 Then Return 255 Else Return c
		
	End If
	
End Function


Code Archives Forum