imblend.m

IMBLEND(FG, BG, OPACITY, BLENDMODE,{AMOUNT},{COMPMODE},{CAMOUNT},{OPTIONS})
	Blend images or imagesets as one would blend layers in GIMP or Photoshop. 

FG, BG are image arrays of same H,V dimension
	Mismatches of dimensions 1:2 are not supported. Use IMRESIZE, IMCROP, 
		or PADARRAY to enforce desired colocation of layer content.
	Mismatches of dimension 3 are handled by array expansion.  
		1 or 3 channel images are assumed to be monochrome or RGB, respectively
		2 or 4 channel images are assumed to have an added alpha channel
		blending a RGB image and a monochrome image results in an RGB image
		blending a I/RGB image with a IA/RGBA image results in an image with alpha
	Mismatches of dimension 4 are handled by array expansion.
		both can be single images or 4-D imagesets of equal length
		can also blend a single image with a 4-D imageset
OPACITY is a scalar from 0 to 1
	defines mixing of blended result and original BG
BLENDMODE is a string assignment (see list & notes) 
	this parameter is insensitive to case and spacing
	see included contour plots for insight into relationships and scaling behaviors
AMOUNT is a numeric parameter (optional, default 1)
	used to internally scale the influence of blend calculations
	modes which accept this argument are marked with effective range
COMPMODE optionally specifies the compositing or alpha blending used for images. (see list)
	default behavior replicates legacy GIMP behavior
CAMOUNT is a thresholding parameter used by some compositing modes (optional, default 1)

OPTIONS may include the following keys:
The user may optionally specify the standard used for luma or YPbPr calculations.
	This only affects modes which perform Y or YPbPr conversion within the scope of imblend.
	'rec601' (default) or 'rec709' are valid keys.
For niche application, a polar color model can be selected with the 'hsy' or 'ypbpr' keys.
	Both modes enforce gamut extents via chroma normalization (hsy) or truncation (ypbpr).
Specifying 'quiet' will suppress non-terminal warnings
Specifying 'verbose' will dump extra information relevant for some modes
	
============================= BLEND MODES =============================
Opacity & Composition
	normal			(compositing only)

Light & Contrast
	overlay         (standard method)                            amount:[0 to +inf)
	hard light      (transpose of overlay)                       amount:[0 to +inf)
	soft light      (legacy GIMP & GEGL)
	soft light ps   (Photoshop)
	soft light svg  (SVG 1.2)
	soft light eb   (EffectBank/illusions.hu)
	soft linear light                                            amount:[0 1]
	linear light    (transpose of softlinearlight)               amount:[0 1]
	vivid light                                                  amount:[0 to +inf)
	flat light      (softdodge & softburn)                       amount:[0 to +inf)
	pin light       (relational highlight & shadow)              amount:[0 1]
	super light     (adjust from linear to pin light)            amount:[1 to +inf)
	hard mix        (similar to posterization)                   amount:[0 2]
	scale add       (add bg to fg deviation from mean)           amount:(-inf to +inf)
	scale mult      (scale bg by mean-normalized fg)             amount:[0 to +inf)
	contrast        (adjust bg contrast by mean-normalized fg)   amount:[0 to +inf)
	curves          (adjust bg contrast directly)                amount:(-inf to +inf)

Dodge & Burn
	color dodge     (similar to GIMP dodge)                      amount:[0 1]
	color burn      (similar to GIMP burn)                       amount:[0 1]
	linear dodge                                                 amount:[0 1]
	linear burn                                                  amount:[0 1]
	soft dodge                                                   amount:[0 to +inf)
	soft burn       (transpose of soft dodge)                    amount:[0 to +inf)
	easy dodge      (improved detail retention)                  amount:[0 to +inf)
	easy burn                                                    amount:[0 to +inf)

Niche Complements from EffectBank
	light           
	shadow          (complement of 'light')
	bright          (like a softer easydodge)
	dark            (complement of 'bright')
	lighteneb       (like a strong softdodge)
	darkeneb        (complement of 'lighteneb')

Quadratics & Complements
	glow            (similar to dodge)                           amount:(-inf to +inf)
	heat            (similar to burn)                            amount:(-inf to +inf)
	reflect         (glow transpose)                             amount:(-inf to +inf)
	freeze          (heat transpose)                             amount:(-inf to +inf)
	helow           (similar to softlight)                       amount:(-inf to +inf)
	gleat           (similar to vividlight)                      amount:(-inf to +inf)
	frect           (helow transpose)                            amount:(-inf to +inf)
	reeze           (gleat transpose)                            amount:(-inf to +inf)

Relational
	lighten RGB     (lighten only (RGB))                         amount:[1 100]
	darken RGB      (darken only (RGB))                          amount:[1 100]
	lighten Y       (lighten only (test luma only))              amount:[1 100]
	darken Y        (darken only (test luma only))               amount:[1 100]
	saturate        (only increase saturation)                   amount:[0 to +inf)
	desaturate      (only decrease saturation)                   amount:[0 to +inf)
	near {layer}	(apply only similar colors)                  amount:[0 1]
	far {layer}     (transpose of 'near')                        amount:[0 1]
	replace color   (replace specified regions of BG)            amount:[0 1]
	exclude color   (transpose of 'replacecolor')                amount:[0 1]

Arithmetic
	multiply
	screen
	divide
	addition
	subtraction
	bleach          (inverse of addition)
	stain           (transpose of bleach)
	difference
	equivalence     (inverse of difference)
	negation                                                     amount:[0 1]
	extremity       (inverse of negation)                        amount:[0 1]
	exclusion 
	interpolate     (cosine interpolation)
	hard int        (quantized cosine interpolation)             amount:[1 to +inf)
	average         (arithmetic mean, linear interpolation)
	geometric       (geometric mean)
	harmonic        (harmonic mean)
	pnorm           (p-norm for p=amount)                        amount:[0 to +inf)
	sqrtdiff
	invsqrtdiff
	arctan
	gammalight      (apply gamma correction map)                 amount:[0 to +inf)
	gammadark       (inverse gamma correction)                   amount:[0 to +inf)
	grain extract
	grain merge

Mesh Effects
	mesh            (apply arbitrary transfer function)          amount:[0 1]
	hard mesh       (apply arbitrary transfer function)          amount:[0 1]
	bomb            (random transfer function)                   amount:[1 to +inf)
	bomb locked     (channel-locked bomb)                        amount:[1 to +inf)
	hard bomb       (think bomb + hardmix)                       amount:[1 to +inf)

Component
	hue             (H in CIELCHab)
	saturation      (C in CIELCHab)
	color           (HS in HSL, preserve Y)
	color lchab     (CH in CIELCHab)
	color lchsr     (CH in SRLAB2 LCH)
	color hsl       (HS in HSL)
	color hsyp      (HS in HSYp)
	value           (max(R,G,B))
	luma            (Rec601 or {Rec709})
	lightness       (mean(min(R,G,B),max(R,G,B))
	intensity       (mean(R,G,B))
	transfer inchan>outchan   (directly transfer any channel to another)
	permute inchan>H     (rotate hue)                            amount:(-inf to +inf)
	permute inchan>HS    (rotate hue and blend chroma)           amount:(-inf to +inf)

NOTES:
	The 'lighten Y', 'darken Y', and some other component modes expect RGB input 
	and will force expansion if fed single-channel images.

	SYNONYMOUS MODES:
	'equivalence' is referred to as 'phoenix' in several sources.
	'average' is referred to as 'allanon' in Krita and EffectBank
	'harmonic' is referred to as 'parallel' in Krita
	'linearburn' is referred to as 'inverse subtract' in Krita
	'sqrtdiff' is referred to as 'additive subtractive' in Krita
	'softlight' is referred to as 'pegtop light' by ImageMagick
	Either name may be used.
	
	OVERLAY & HARDLIGHT MODES:
	For AMOUNT=1, these behave as per standard formulae. Otherwise, an alternative is used.
	These are custom mesh modes which approximate iterated application of the named blend
	in a fashion which is continuously scalable so as to simulate fractional iterates.
	Consider the following examples using 'overlay'
		For AMOUNT=0.7, results approximate a softlight blend
		For AMOUNT=1, results are identical to standard methods
		For AMOUNT=2, results approximate imblend(FG,imblend(FG,BG,1,'overlay'),1,'overlay')

	SOFT LIGHT:
	'softlight' is equivalent to ImageMagick, GIMP, and GEGL code.  Also known as 'pegtop light'.
	'softlightps' is equivalent to all formulae found attributed to Photoshop (afaik).
	'softlightsvg' follows SVG 1.2 spec, and is nearly identical to 'softlightps'.
	'softlighteb' uses a method posed for EffectBank by illusions.hu

	PIN LIGHT:
	This mode combines lighten-only and darken-only thresholding to allow incorporation of FG
	extrema into the BG image.  As AMOUNT is decreased, the thresholding becomes more exclusive.

	SUPER LIGHT:
	Piecewise union of functions whose level curves are superelliptic.  Allows transition between
	behaviors of other blend modes. Useful in place of 'pin light' if a soft threshold is desired.
		For AMOUNT=1, behavior matches 'linear light'
		For AMOUNT=2, behavior is similar to 'hard light'
		For AMOUNT>>2, behavior approaches 'pin light'

	FLAT LIGHT:
	This is a piecewise combination of 'softdodge' & 'softburn'.  The effect is flat and somewhat
	opaque, tending to superimpose FG extrema.  The result is a middle ground between the behaviors 
	and utility of 'vividlight' and 'pinlight'.  

	MEAN-CENTERED CONTRAST MODES:
	The modes 'scale add', 'scale mult', and 'contrast' are intended for uses similar to those of GIMP's
	'grain merge' mode.  In normal operation, the FG content is treated as a mean-centered gain map for
	the blend effect in question.  As an alternative to mean-centering, the center color may be specified
	via AMOUNT in the form of [k cc], where k is the scaling factor and cc is the center color, which may
	be either 1 or 3 elements;  i.e. [1 0.5] is equivalent to [1 0.5 0.5 0.5].  In this fashion, 'scale add'
	and 'scale mult' effect adjustable additive and multiplicative gain mapping.  'contrast' acts as a 
	levels tool, shifting the BG input white point or black point depending on FG value. This mode is
	similar to a subtle application of 'vivid light', with its breakpoints controlled by the center color.
	When cc=0 or 1, 'contrast' becomes equivalent to 'color dodge' or 'color burn'.  

	CURVES:
	This mode allows direct manipulation of BG contrast in a fashion similar to that of a curves tool.
	This mode can take up to three parameters via AMOUNT.  A full specification is of the form [k os gp],
	where k is a scaling factor, os is an offset (default 0), and gp is the input grey value (default 0.5).
	The amount of curvature is modulated following C=(k*FG + os), and the midpoint of the curve is shifted 
	by gp.  Setting k=0 allows scalar manipulation of contrast without the necessity for a solid FG fill.
		When C>1, BG contrast is increased
		When 01, BG content remains dominant; for AMOUNT<1, FG content dominates.  
	See contour plots for insight.  These modes have no neutral FG color.

	EASY DODGE & BURN:
	These are modified power functions allowing scalable dodge/burn functionality without destroying
	highlight and shadow details.  As traditional methods are constant-valued for 50% of their
	domain, they tend to exhibit a thresholding behavior.  While 'easydodge' and Gruschel's 'softdodge'
	can both darken and lighten, 'easydodge' is more asymmetric and has only subtle darkening effect.
	Unlike 'color' or 'linear' dodge & burn, the neutral FG color for the 'easy' modes is not black/white, 
	but 1/6 and 5/6 (for AMOUNT=1). Results from 'easydodge' tend to be soft and less-oversaturated,  
	as if a compromise between 'colordodge' and 'screen'.  These are good all-around tools for dodge/burn  
	tasks where extra contrast stretching is desired.

	QUADRATIC MODES:
	'glow' and 'heat' are higher-ordered variants of 'colordodge' and 'colorburn'. Compared to the  
	latter, they have subdued effect for default AMOUNT, though they are largely constant-valued 
	and exhibit the same thresholding behavior.  While both color and linear dodge/burn are unidirectional, 
	these modes can both lighten and darken an image. The complementary modes 'gleat' and 'helow' are 
	symmetric modes derived from the prior.  'gleat' behaves similar to 'vividlight', whereas 'helow' 
	is similar to 'overlay' but with the midtone contrast response inverted (see contour plots).
	'helow' and its transpose do not exhibit thresholding.

	LIGHTEN & DARKEN: 
	The RGB modes are simple max/min relationals, much like GIMP's 'lighten only' and 'darken only'.
	The hard edge of these RGB modes can be tempered by specifying a range of smooth transition.  
	For AMOUNT=1, the operation is simple relational. Otherwise, AMOUNT specifies the width of the 
	transition region about the unit square diagonal (in percent).  When AMOUNT=100, no unaltered FG
	or BG content remains; a value of 10% or so helps reduce the appearance of transition edges.

	'lighteny' and 'darkeny' are similar to Photoshop's 'lighter color' and 'darker color' modes. 
	Here, the FG/BG pixel luma is evaluated and the pixels replaced as a whole instead of evaluating 
	each channel. This results in a binary masking behavior when AMOUNT=1. Otherwise, the transition
	between FG and BG is a linearized opacity blend.  This is a tentative measure to reduce perceived
	brightness inversions or banding which otherwise occur in the blended region.

	DISTANCE MODES:
	The modes 'near' and 'far' locate regions in which FG and BG colors are within or beyond a weighted
	euclidean distance.  Both modes accept an optional argument {layer} which may be 'fg' or 'bg'.
		'near fg' will return only the FG content in the match region
		'near bg' will return only the BG content in the match region
		'near' merges matching FG content into BG
	For RGB inputs, distance calculation is performed in YPbPr, with extra weighting on luma.
	For distance specified by AMOUNT>=1, all colors are considered 'near'.

	REPLACE & EXCLUDE COLOR:
	These incorporate simple masking behavior which allows the user to handle composition with
	solid-color image matting.  For example, if AMOUNT=[0 0 0], 'replacecolor' copies FG data  
	to all black BG regions; 'excludecolor' copies all non-black FG content to the BG.  
	If AMOUNT is a scalar, it will be expanded as necessary. Masking has a tolerance of 1%

	SATURATE & DESATURATE:
	Unlike the component mode 'saturation', these are thresholding modes operating on chroma 
	in LCHab, much like 'lightenrgb' or 'lighteny' operates on rgb channels and luma. In these
	modes, AMOUNT modulates foreground chroma.

	KRITA & EFFECTBANK/ILLUSIONS.HU MODES:
	'light' and 'shadow' are strong dodge/burn-like modes
	'bright' and 'dark' are soft, partially inverting dodge/burn-like modes
	'lighteneb' and 'darkeneb' are similar to a strong, transposed softdodge/burn
	'gammalight' and 'gammadark' allow gamma adjustment with AMOUNTxFG as a gamma map.
	'bleach' and 'stain' are the inverse of 'lineardodge' (addition), and 'linearburn'
	'sqrtdiff', aka 'additivesubtract' is the difference of square roots
	'harmonic', aka 'parallel' is the harmonic mean; roughly equivalent to 'geometric'
	'arctan' is similar to 'softdodge' with an inverted FG

	MESH MODES:
	These modes accept AMOUNT in the form of a 2x2 or larger matrix whose elements represent
	output intensity for input intensities from 0 to 1 (consider BG as horizontal axis, etc)
	e.g [0 0.5; 0.5 1] is equivalent to 'average'; [0 0; 1 1] is the same as 'normal'
	Compare to the included contour plots; amount(1,1) is at the origin of BG and FG axes.
	Values are assumed to be evenly spaced and are subject to interpolation (bilinear for 'mesh' 
	and nearest-neighbot for 'hardmesh'). If AMOUNT is not set explicitly to a valid matrix, 
	a warning will be dumped and a default used.

	RANDOMIZED MODES:
	The 'bomb' mode applies a random piecewise-linear blend function of size AMOUNTxAMOUNT
	The 'bomblocked' mode is the same as 'bomb', but without channel-independence
	The 'hardbomb' mode applies a random piecewise-constant blend function of size AMOUNTxAMOUNT
	Using the 'verbose' key with these modes will display the transformation matrix as a command string.
	These can then be used with the mesh modes to reproduce a particular random blend. 
	
	COLOR MODES: 
	'color' is a variant of the HSL method with an attempt to enforce luma preservation (fast)
	'color hsyp' attempts to provide best uniformity, at the cost of maximum chroma range.
	'color hsl' matches the legacy 'color' blend mode in GIMP
	 Based only on experiment, LCHab method best approximates Photoshop behavior.

	The 'hue' & 'saturation' modes are derived from LCHab instead of HSL as in GIMP.
	If H or S modes are desired in HuSL, HSY, HSI or HSV, use 'transfer' instead.

	TRANSFER MODES:
	mode accepts channel strings based on RGBA, HuSLuv, HSY, HSYp, HSI, HSL, HSV, or CIELCHab models
		'y', 'r', 'g', 'b', 'a'
		'h_husl', 's_husl', 'l_husl'
		'h_hsy', 's_hsy', 'y_hsy'
		'h_hsyp', 's_hsyp', 'y_hsyp'
		'h_hsi', 's_hsi', 'i_hsi'
		'h_hsl', 's_hsl', 'l_hsl'
		'h_hsv', 's_hsv', 'v_hsv'
		'l_lch', 'c_lch', 'h_lch'
	non-rgb symmetric channel transfers (e.g. V>V or Y>Y) are easier applied otherwise
		(e.g. 'value' or 'luma' blend modes)

	PERMUTATION MODES:
	modes can accept input channel strings 'h', 's', 'y', 'dh', 'ds', 'dy'
	permutations actually occur on H and S in the HuSLuv model
	color permutations (inchan>HS) combine hue rotation and chroma blending
	chroma blending is maximized when abs(amount)==1

============================= COMPOSITION MODES =============================
Porter-Duff 
	src over                                                     camount:[0 to +inf)
	src atop                                                     camount:[0 to +inf)
	src in                                                       camount:[0 to +inf)
	src out                                                      camount:[0 to +inf)
	dst over                                                     camount:[0 to +inf)
	dst atop                                                     camount:[0 to +inf)
	dst in                                                       camount:[0 to +inf)
	dst out                                                      camount:[0 to +inf)
	xor                                                          camount:[0 to +inf)

Other
	gimp                (default)
	translucent     
	dissolve {type}     (alpha dithering)                        camount:[0 1]
	lindissolve {type}  (preserve linear alpha)                  camount:[0 1]

NOTES:
	Some of these modes (e.g. 'dst in', 'xor') don't really make much sense to use with
	any blend mode other than 'normal'.  You're not restricted from doing it, though.
	
	'gimp' specifies the legacy approach used by GIMP prior to GEGL (default)
	This is similar to SRC-OVER composition for 'normal' and a modified SRC-ATOP 
	composition for other blends

	The SVG 1.2 spec and GEGL follow a Porter-Duff SRC-OVER composition for all blends

	PORTER-DUFF MODES:
	If using these modes where hard-edged masking behavior is desired, specifying a nonunity CAMOUNT 
	will invoke a thresholding operation on the FG alpha channel.  
		CAMOUNT>1 sets all alpha <1 to 0
		CAMOUNT between (0,1) thresholds alpha at the specified value
		CAMOUNT=0 will set all nonzero alpha to 1
	Unlike other modes, using these on I/RGB inputs may force IA/RGBA output depending on the mode
	and the value of specified OPACITY.  These are generally not useful cases.

	TRANSLUCENT MODE:
	This mode is based on an article by Søren Sandmann Pedersen, and uses a transmission-reflection
	model to emulate the effect of a translucent material. Calculations are performed in linear RGB.
	http://ssp.impulsetrain.com/translucency.html

	DISSOLVE MODES:   
	These modes are essentially SRC-OVER composition after FG alpha is converted to a dithered
	binary mask using one of the following methods:
		'dissolve' applies a white noise thresholding dither (GIMP behavior)
		'dissolve ord' applies a 64-level ordered dither
		'dissolve zf' applies a Zhou-Fang variable-coefficient E-D dither (best)
	When using these modes, final mixdown opacity is linearly scaled with OPACITY as usual.
	The masking density is controlled via CAMOUNT. The combination of dithering and linear opacity
	makes the creation of texture or grain overlays very simple.

	The 'lindissolve' modes offer the same methods, but the dithering is performed only on a uniform 
	mask.  This leaves linear FG alpha intact, allowing for a different range of control. i.e.:
		In 'dissolve', opacity is scalar (OPACITY) and density is a map (alpha*CAMOUNT)
		In 'lindissolve', opacity is a map (alpha*OPACITY) and density is scalar (CAMOUNT)
	When no FG alpha channel is present, 'dissolve' and 'lindissolve' are identical.

=====================================================================
EXAMPLES:
   Do a simple multiply blend as would GIMP:
	   R=imblend(FG,BG,1,'multiply');

   Specify SRC-OVER composition and use CAMOUNT for alpha thresholding:
	   R=imblend(FG,BG,1,'multiply','srcover',0.5);          

CLASS SUPPORT:
	Accepts 'double','single','uint8','uint16','int16', and 'logical'
	Return type is inherited from BG
			

The synopsis says it all. Between IMBLEND() and REPLACEPIXELS(), the layer blending functionality of common image manipulation programs can be replicated in MATLAB. This function offers dimensional flexibility, influence scaling, and so many blend modes I can't even keep track of them all. The 'transfer' and 'permute' modes are parametric and can be specified to operate on various channels. I assert that if nothing else, IMBLEND() stands as the single most comprehensive collection and demonstration of blend mode math from GIMP, ImageMagick, Photoshop, Krita, and elsewhere.

Many of these modes are parametric, accepting an input 'amount'. This allows adjusting behavior such as the influence of a dodge/burn, the angle of a hue permutation, or the polynomial order of the quadratic modes. This added functionality allows these modes to have a broad range of effects, and in the case of the quadratic modes, complementary effects. Take a look at some of the contour plots for a better idea.

Regarding compositing when processing images with transparency, two operating modes are available. The default is to use the legacy method used by GIMP. This is not equivalent to Porter-Duff SRC-OVER composition and may be undesired if one expects behavior similar to other applications. This behavior is selected as the default merely for speed reasons. Currently, the SVG compositing methods are non-optimized and are generally slower. When neither image has an alpha channel, both compositing modes are equivalent and the output is processed in a simplified manner. All blend modes are available to either composition mode.

Although it is of limited use, IMBLEND() can also be configured to internally operate on HSY or YPbPr channels as it would otherwise operate on RGB.

Notes regarding specific modes:

While the 'normal' mode is conceptually identical to 'src-over', it is handled differently, as there exists a slightly different compositing method by the same name when in GIMP compositing mode. All other modes in this group are implicitly handled by the SVG/PD compositing method, and the COMPOSITE parameter will have no effect.

Information about 'translucent' can be found at http://ssp.impulsetrain.com/translucency.html

The 'overlay' mode implemented by legacy (<=2.8) GIMP matches 'softlight' due to a bug. Keep this in mind if trying to emulate GIMP behavior.

The SVG 1.2 documentation specifies a variant hereby called 'soft light svg' which differs from the standard 'softlight' for M>0.5. In this new mode, M has greater influence over dark I than in the standard method. See contour plots for a graphical description of the asymmetry. Although GEGL methods used by GIMP 2.9+ are generally based on SVG 1.2, the 'softlight' method used there matches the legacy behavior rather than the SVG method. Other softlight variants are included to replicate behavior attributed to Photoshop and EffectBank/illusions.hu. Without either of these applications, I cannot verify the accuracy of the math. Other formulae (including obviously incorrect ones) have been attributed to both.

The 'scaleadd', 'scalemult', and 'contrast' modes are conceptually similar to 'grainmerge', in that they are intended to take the FG intensity variance and apply it to increase the contrast of the BG. Where 'grainextract' and 'grainmerge' assume an image mean of 0.5, these three modes take the individual channel means. When the image mean is 0.5 and AMOUNT==1, 'scaleadd' and 'grainmerge' are identical.

The so-called quadratic modes are useful for contrast/light and dodge/burn effects. With parameterization via AMOUNT, the actual order of numerator isn't strictly quadratic, but is of order (AMOUNT+1). Included are four split methods of my own concoction. I find these to be more useful than the standard quadratics, especially if you consider the flexibility provided by AMOUNT. Compare 'helow' to 'overlay' and 'softlight' for AMOUNT=0.4-0.6. Compare 'gleat' to 'vividlight'.

These modes are non-commutative, but form complementary pairs in two senses. 'glow' is the same as 'reflect' with the layers swapped (transposed). The same goes for 'heat' and 'freeze', 'gleat' and 'reeze', 'helow' and 'frect'. Also, when considering the fact that AMOUNT can be negative, reflect(amount)=1-heat(-(amount+1)). The same is true for 'freeze' and 'glow', 'frect' and 'gleat', 'reeze' and 'helow'. The contour plots illustrate these properties clearly.

'lighteny' and 'darkeny' are similar to Photoshop's 'lighter color' and 'darker color' modes. Here, the FG/BG pixel luma is evaluated and the pixels replaced as a whole instead of evaluating each channel. This results in a binary masking behavior.

'color' blend modes are available to match the legacy behavior of GIMP, as well as the GEGL/Photoshop behavior. The standard 'color' mode is a variant of the legacy GIMP method.

The 'transfer' and 'permute' modes are parametric and can be specified to operate on various channels.

 

Example 1:
Generate some circles and perform a softlight blend similar to GIMP's 'overlay' mode

bg=imread([projdir 'sources/probe.jpg']);
fg=randspots(size(bg),10,[50 150],[0.5 1],'circle');

outpict=imblend(fg,bg,1,'softlight',1);

imshow(outpict)
				
 
 

Example 2:
This dodge operation is blown out.
How can this be tuned down?

bg=imread([projdir 'sources/probe.jpg']);
fg=imread([projdir 'sources/probegrad.jpg']);

outpict=imblend(fg,bg,1,'colordodge',1);

imshow(outpict)
				
 
 

Example 3:
Most image manipulation suites only offer opacity reduction
This doesn't solve anything here.

bg=imread([projdir 'sources/probe.jpg']);
fg=imread([projdir 'sources/probegrad.jpg']);

outpict=imblend(fg,bg,0.5,'colordodge',1);

imshow(outpict)
				
 
 

Example 4:
Using the AMOUNT parameter scales the influence like we need.

bg=imread([projdir 'sources/probe.jpg']);
fg=imread([projdir 'sources/probegrad.jpg']);

outpict=imblend(fg,bg,1,'colordodge',0.5);

imshow(outpict)
				
 
 

Example 5:
Create an extreme test pattern and apply it to test each of the 'color' blend modes. Extract the mean luma/lightness differences between the original background and the result. Concatenate images for comparison.

Note the effects on shadows and specular highlights. The brightness preservation in 'color' and the HSY/LCH modes helps reduce the effect of fg color on perceived brightness, vastly increasing the utility of these modes for colorizing without altering perceived brightness. Note how the symmetric 'color hsyp' mode helps avoid nonuniformity in regions dominated by saturated primary and secondary colors.

See CSVIEW, RGB2HSY, and RGB2HUSL pages for more information. Also see commentary: http://epicbeardquest.blogspot.com/2015/11/exploring-color-blend-mode.html

imread('sources/table.jpg');

s=size(bg);
hx=0:360/s(2):(360-360/s(2));
hy=0:180/s(1):(180-180/s(1));
[Hx Hy]=meshgrid(hx,hy);
S=ones(size(Hx))*0.8;
Y=ones(size(Hx))*0.5;
fg1=hsy2rgb(cat(3,mod(Hx+Hy,360),S,Y),'pastel');

fg2=flipdim(fg1,1);
mask=eoline(true(s(1:2)),2,[20 40]);
fg=replacepixels(fg1,fg2,mask);

A=imblend(fg,bg,1,'color');
B=imblend(fg,bg,1,'color lchab');
C=imblend(fg,bg,1,'color lchsr');
D=imblend(fg,bg,1,'color hsyp');
E=imblend(fg,bg,1,'color hsl');

Y0=double(mono(bg,'y'));
L0=double(mono(bg,'llch'));
a=uint8((abs(Y0-double(mono(A,'y')))+abs(L0-double(mono(A,'llch'))))/2);
b=uint8((abs(Y0-double(mono(B,'y')))+abs(L0-double(mono(B,'llch'))))/2);
c=uint8((abs(Y0-double(mono(C,'y')))+abs(L0-double(mono(C,'llch'))))/2);
d=uint8((abs(Y0-double(mono(D,'y')))+abs(L0-double(mono(D,'llch'))))/2);
e=uint8((abs(Y0-double(mono(D,'y')))+abs(L0-double(mono(D,'llch'))))/2);

limits=stretchlim(cat(1,a,b,c,d,e));
error1=repmat(imadjust(cat(1,a,b,c,d,e),limits),[1 1 3]);
color1=cat(1,A,B,C,D,E);
group1=cat(2,color1,error1);

imshow(255-group1)
imwrite(fg,'examples/imblendex6.jpg','jpeg','Quality',90);
imwrite(group1,'examples/imblendex7.jpg','jpeg','Quality',90);
				
 
 

Example 6:
Demonstrate contrast-scaling blend modes. In this example, a low-contrast FG is used to emphasize how the normalization and scaling allows FG variation to influence BG contrast regardless of mean FG value.

bg=imread('sources/table.jpg');

s=size(bg);
fg1=lingrad(s,[0 0; 1 1],([0 0 0; 1 1 1]+2)*255/4);
fg2=flipdim(fg1,1);
mask=eoline(true(s(1:2)),2,[20 40]);
fg=replacepixels(fg1,fg2,mask);

A=imblend(fg,bg,1,'scale add');
B=imblend(fg,bg,1,'scale mult');
C=imblend(fg,bg,1,'contrast');

group=cat(1,A,B,C);

imshow(255-group)
imwrite(fg,'examples/imblendex10.jpg','jpeg','Quality',90);
imwrite(group,'examples/imblendex11.jpg','jpeg','Quality',90);
				
 
 

Example 7:
Demonstrate hue and saturation/chroma channel transfers. While the named "hue" and "saturation" modes use LCHab, other methods can be explicitly selected with "transfer".

bg=imread('sources/table.jpg');

s=size(bg);
fg1=lingrad(s,[0 0; 1 1],[1 0 0; 1 1 0; 0 1 0; 0 1 1; 0 0 1; 1 0 1; 1 0 0]*255);
sgrad=lingrad(s,[0 0; 1 0],[0 0 0; 1 1 1]*255);
vgrad=lingrad(s,[1 0; 0 0],[0 0 0; 1 1 1]*255);
fg1=imblend(sgrad,fg1,1,'transfer v_hsv>s_hsv');
fg1=imblend(vgrad,fg1,1,'transfer v_hsv>v_hsv');
fg2=flipdim(fg1,1);
mask=eoline(true(s(1:2)),2,[20 40]);
fg=replacepixels(fg1,fg2,mask);

A=imblend(fg,bg,1,'transfer hhsv>hhsv');
B=imblend(fg,bg,1,'transfer hhsi>hhsi');
C=imblend(fg,bg,1,'transfer hlch>hlch');
D=imblend(fg,bg,1,'transfer hhusl>hhusl');

E=imblend(fg,bg,1,'transfer shsv>shsv');
F=imblend(fg,bg,1,'transfer shsi>shsi');
G=imblend(fg,bg,1,'transfer clch>clch');
H=imblend(fg,bg,1,'transfer shusl>shusl');

group1=cat(1,cat(2,A,B),cat(2,C,D));
group2=cat(1,cat(2,E,F),cat(2,G,H));

imshow(255-group1)
imwrite(fg,'examples/imblendex12.jpg','jpeg','Quality',90);
imwrite(group1,'examples/imblendex13.jpg','jpeg','Quality',90);
imwrite(group2,'examples/imblendex14.jpg','jpeg','Quality',90);
				
 
 

Example 8:
Demonstrate relational modes. Note how luma-only methods have hard edges. This is because these methods are essentially just masking functions. RGB relational blending effects a 2-bit (4-level) mask, whereas a single-channel method results in a binary mask. This is similar to the 'lighter color' and 'darker color' modes in Photoshop CS3/CS4.

bg=imread('sources/table.jpg');

s=size(bg);
fg1=lingrad(s,[0 0; 1 1],[1 0 0; 1 1 0; 0 1 0; 0 1 1; 0 0 1; 1 0 1; 1 0 0]*255);
sgrad=lingrad(s,[0 0; 1 0],[0 0 0; 1 1 1]*255);
vgrad=lingrad(s,[1 0; 0 0],[0 0 0; 1 1 1]*255);
fg1=imblend(sgrad,fg1,1,'transfer v_hsv>s_hsv');
fg=imblend(vgrad,fg1,1,'transfer v_hsv>v_hsv');

A=imblend(fg,bg,1,'lighten rgb');
B=imblend(fg,bg,1,'lighten y');
C=imblend(fg,bg,1,'darken rgb');
D=imblend(fg,bg,1,'darken y');

group=cat(1,cat(2,A,B),cat(2,C,D));

imshow(255-group)
imwrite(fg,'examples/imblendex15.jpg','jpeg','Quality',90);
imwrite(group,'examples/imblendex16.jpg','jpeg','Quality',90);
				
 
 

Example 9:
Demonstrate the difference in image composition for partially transparent images using a 'multiply' blend mode. The legacy GIMP compositing method roughly approximates a SRC-OVER composition for 'normal' mode and a 'SRC-ATOP' composition for all other blend modes. The primary deviation being that the source alpha is initially recalculated as Sa=min(Sa,Da). Don't ask me why.

The SVG modes are essentially a Porter-Duff SRC-OVER composition.

[fg,~,fga]=imread('sources/bluebars.png');
[bg,~,bga]=imread('sources/redbars.png');
fg=cat(3,fg,fga);
bg=cat(3,bg,bga);

svgmult=imblend(fg,bg,1,'multiply','svg');
gimpmult=imblend(fg,bg,1,'multiply','gimp');

group=cat(1,svgmult,gimpmult);

imshow(255-group(:,:,1:3))