Image blending can easily help you seamlessly blend two images together to create another different special effect. Image blending has been seen in almost all of the image processing program. iPaintPro implements most of the often seen image blending mode in Adobe Photoshop. In this post I will reveal the algorithms I used for each of the blending method with a screenshot to show you the effect. However, I am not guarantee that will be truly the algorithms used in Adobe Photoshop.
Since there are so many different blending methods, I will split this topic in a series of post.
Before we start, let’s create a generic function blending_canvas(canvas1,cavas2,blending_mode). This function will blend canvas1 into canvas2 using specified blending_mode. We will implement each blending_mode into a global object BLENDING_MACRO that is called within this function.
// blend canvas1 to canvas2 using given blending_mode
function blending_canvas(canvas1, canvas2, blending_mode){
// Although it doesn't have to be, but for the sake of simplicity, let's assume
// the two canvas must have same size;
if ( canvas1.width != canvas2.width || canvas1.height != canvas2.height ){
return canvas2;
}
var ctx1 = canvas1.getContext("2d"),
ctx2 = canvas2.getContext("2d");
var data1 = ctx1.getImageData(0,0,canvas1.width,canvas2.height).data;
var imgData = ctx2.getImageData(0,0,canvas1.width,canvas2.height);
var data2 = imgData.data;
for ( var i = 0; i < data1.length; i += 4 ){
//blending red channel
data2[i] = BLENDING_MACRO[blending_mode](data1[i],data2[i]);
//blending green channel
data2[i+1] = BLENDING_MACRO[blending_mode](data1[i],data2[i+1]);
//blending blue channel
data2[i+2] = BLENDING_MACRO[blending_mode](data1[i],data2[i+2]);
}
ctx2.putImageData(imgData,0,0);
return canvas2;
}
Ok, with this powerful function ready in hand, let’s buckle up and start our journey…
Blending Mode: Multiply
Code Fragment:
//v1: channel value taken from source image
//v2: channel value taken from destination image
var BLENDING_MACRO = {
multiply: function(v1,v2){
return v1* v2 / 255;
}
};
}
Now to multiply two canvas, we can simply call our generic method using this macro.
blending_canvas(canvas1,canvas2,"multiply");
Blending Effect Screenshot taken from iPaintPro:
Blending Mode: Screen
Code Fragment:
//v1: channel value taken from source image
//v2: channel value taken from destination image
var BLENDING_MACRO = {
multiply: function(v1,v2){return v1 * v2 / 255;},
screen:function(v1,v2){
// some web page present the formula as:
// 255 – ( 255 – v1 ) * ( 255 – v2 ) / 255
// With a little mathematic reasoning, you will found that they are equivalent
// but with less burden to the cpu.
return v1 + v2 – v1 * v2/ 255;
}
};
}
Now to apply the Screen blending mode to two canvas, we can simply call our generic method using this macro.
blending_canvas(canvas1,canvas2,"screen");
Blending Effect Screenshot taken from iPaintPro:
Blending Mode: Overlay
Code Fragment:
//v1: channel value taken from source image
//v2: channel value taken from destination image
var BLENDING_MACRO = {
multiply: function(v1,v2){return v1 * v2 / 255;},
screen : function(v1,v2){return v1 + v2 – v1 * v2 / 255;},
overlay : function(v1,v2){
return (v2 < 128) ? (2 * v1 * v2 / 255):(255 - 2 * (255 - v1) * (255 - v2) / 255);
}
};
Now to apply the Overlay blending mode to two canvas, we can simply call our generic method using this macro.
blending_canvas(canvas1,canvas2,"overlay");
Blending Effect Screenshot taken from iPaintPro:
Blending Mode: Soft Light
Code Fragment:
//v1: channel value taken from source image
//v2: channel value taken from destination image
var BLENDING_MACRO = {
multiply: function(v1,v2){return v1 * v2 / 255;},
screen : function(v1,v2){return v1 + v2 – v1 * v2 / 255;},
overlay : function(v1,v2){
return (v2 < 128) ? (2 * v1 * v2 / 255):(255 - 2 * (255 - v1) * (255 - v2) / 255);
},
softlight: function (v1,v2){
if ( v1 > 127.5 ){
return v2 + (255 - v2) * ((v1 - 127.5) / 127.5) * (0.5 - Math.abs(v2-127.5)/255);
}else{
return v2 - v2 * ((127.5 - v1) / 127.5) * (0.5 - Math.abs(v2-127.5)/255);
}
}
};
Now to apply the Soft Light blending mode to two canvas, we can simply call our generic method using this macro.
blending_canvas(canvas1,canvas2,"softlight");
Blending Effect Screenshot taken from iPaintPro:
Blending Mode: Hard Light
Code Fragment:
//v1: channel value taken from source image
//v2: channel value taken from destination image
var BLENDING_MACRO = {
multiply: function(v1,v2){return v1 * v2 / 255;},
screen : function(v1,v2){return v1 + v2 – v1 * v2 / 255;},
overlay : function(v1,v2){
return (v2 < 128) ? (2 * v1 * v2 / 255):(255 - 2 * (255 - v1) * (255 - v2) / 255);
},
softlight: function (v1,v2){
if ( v1 > 127.5 ){
return v2 + (255 - v2) * ((v1 - 127.5) / 127.5) * (0.5 - Math.abs(v2-127.5)/255);
}else{
return v2 - v2 * ((127.5 - v1) / 127.5) * (0.5 - Math.abs(v2-127.5)/255);
}
},
hardlight: function (v1,v2){
if ( v1 > 127.5 ){
return v2 + (255 - v2) * ((v1 - 127.5) / 127.5);
}else{
return v2 * v1 / 127.5;
}
}
};
Now to apply the Hard Light blending mode to two canvas, we can simply call our generic method using this macro.
blending_canvas(canvas1,canvas2,"hardlight");
Blending Effect Screenshot taken from iPaintPro:
