HTML5 canvas filters on images

Published on by Yousfi Benameur

Remember these codes work only with ie emulation as pointed in previous posts (otherwise have  fired errors when running).These codes are tested on IE11 emulation.

JavaScript is still essential to work with canvas.

I used a mixed code vfp/javascript to work with canvas because the DOM way dont work as well with vfp (see also the previous posts).

Instead a vfp form i use this once an internet explorer application whose can access to the fullscreen easily.

Important : to avoid some problems with IE run vfp always as administrator.


With html5 canvas can draw any image with any dimensions specified.








This drawimage function desserves also the resize operation of original image to any dimensions.









Can apply filters on any image drawn as follow









-a linear gradient object with many colors.The colors can be transparent with applying rgba (alpha channel used) for this purpose.








-A  radial gradient object with many colors.The colors can be also transparent with applying RGBA( and its alpha channel).









-Any rgba color with the alpha channel tranparent (transparency between 0-1).









this code uses theses idea to make a filter on image and capture the entier compound as image







the code uses the context ('2d') property:





ctx.globalCompositeOperation = "destination-over";






see some screenshots below.





 

*1*apply a transparent filter gradient on any image.

 

Declare Integer BringWindowToTop In user32 Integer

Declare Integer SetWindowText In user32 Integer HWnd, String lpstring

Declare Integer Sleep In kernel32 Integer

Publi apie

apie=Newobject("internetexplorer.application")

apie.Navigate("about:blank")

Sleep(500)

With apie

TEXT to m.myvar textmerge noshow

<body topmargin=0 leftmargin=0 bgcolor="black" scroll="no" oncontextmenu="window.close();return false;" >

<canvas id="ycanvas1" width="<<sysmetric(1)>>" height="<<sysmetric(2))>>" ></canvas>

</body>

ENDTEXT

.Document.body.outerhtml=.Document.body.outerhtml+m.myvar

Endwith

Local m.xpict

m.xpict=Getpict()

If Empty(m.xpict)

Return .F.

Endi

m.xpict=Strtran(m.xpict,'\','/')

Local m.rep,m.xx

m.rep=Int(Val(Inputbox("LinearGradient (1) or radialgradient(2) or color(3)","choose gradient/color","1")))

If !Between(m.rep,1,3)

m.rep=1

Endi

 

Do Case

Case m.rep=1

TEXT to m.xx noshow

var my_gradient=ctx.createLinearGradient(0,0,canvas.width,0);

my_gradient.addColorStop(0, "rgba(0, 215, 0, 0.75)");

my_gradient.addColorStop(0.3,"rgba(205, 0, 0, 0.5)");

my_gradient.addColorStop(0.5,"rgba(105, 0, 205, 0.3)");

my_gradient.addColorStop(0.7,"rgba(0, 215, 205, 0.5)");

my_gradient.addColorStop(1,"rgba(205, 215, 0, 0.5)");

ctx.fillStyle=my_gradient;

ENDTEXT

 

Case m.rep=2

TEXT to m.xx noshow

var my_gradient=ctx.createRadialGradient(canvas.width/2,canvas.height/2,50,canvas.width/2,canvas.height/2,canvas.width/2);

my_gradient.addColorStop(0, "rgba(0, 215, 0, 0.75)");

my_gradient.addColorStop(0.3,"rgba(205, 0, 0, 0.5)");

my_gradient.addColorStop(0.5,"rgba(105, 0, 205, 0.3)");

my_gradient.addColorStop(0.7,"rgba(0, 215, 205, 0.5)");

my_gradient.addColorStop(1,"rgba(205, 215, 0, 0.5)");

ctx.fillStyle=my_gradient;

ENDTEXT

 

Case m.rep=3

Local xcolor

m.xcolor=Getcolor()

If Empty(m.xcolor)

m.xcolor=Rgb(0,255,0)

Endi

Local RGBChr,r,g,b,ycolor

m.RGBChr=Left(BinToC(m.xcolor,'R'),3)

r=Asc(Substr(m.RGBChr,1,1)) && RED

g=Asc(Substr(m.RGBChr,2,1)) && GREEN

b=Asc(Substr(m.RGBChr,3,1)) && BLUE

ycolor='rgba('+Trans(r,'999')+','+Trans(g,"999")+','+Trans(b,'999')+',0.5)'

 

TEXT to m.xx textmerge noshow

ctx.fillStyle='<<m.ycolor>>';

ENDTEXT

Endcase

 

TEXT to m.myvar textmerge noshow

var canvas=document.getElementById("ycanvas1");

canvas.style.background="black";

var ctx = canvas.getContext("2d");

img=new Image();

img.src=' <<xpict>> '  ;

img.onload = function () {

ctx.drawImage(img, 0, 0,canvas.width,canvas.height);

}

ctx.globalCompositeOperation = "destination-over";

<<m.xx>>

ctx.fillRect(0,0,canvas.width,canvas.height);

ENDTEXT

 

With apie.Document

x=.createElement("SCRIPT")

x.Id="yscript"

T =.createTextNode(m.myvar)

x.appendChild(T)

.body.appendChild(x)

Endwith

Sleep(2000)

*_cliptext=m.myvar

With apie

.menubar=0

.Toolbar=0

.StatusBar=0

*if want a normal window (adapt dimensions)

*.width=800

*.height=600

*.top=50

*.left=(sysmetric(1)-.width)/2

 

.fullscreen=1

BringWindowToTop(.HWnd)

SetWindowText(.HWnd, "Html5 canvas image with transparent gradient")

.Visible=.T.

 

Local m.mess

TEXT to m.mess noshow

-Right click or CTRL+F4 to close the fullscreen window!

-The screen capture is in clipboard-Run MSPAINt and paste it as

(PNG,JPG,BMP,GIF...)

ENDTEXT

Messagebox(m.mess,0+32+4096,'',1500)

Sleep(500)

ycap()

 

Endwith

 

Retu

 

Function ycap()

Declare Integer keybd_event In Win32API INTEGER, Integer, Integer, Integer

VK_SNAPSHOT = 44 && from the winuser.h

VK_LMENU = 164

KEYEVENTF_KEYUP = 2

KEYEVENTF_EXTENDEDKEY = 1

DoEvents

keybd_event(VK_SNAPSHOT, 1, 0, 0 )

keybd_event(VK_SNAPSHOT, 1, KEYEVENTF_KEYUP, 0 )

DoEvents

 

Inkey(0.5)

*if want to show Mspaint and the captured picture pasted on

*_screen.windowstate=1

*run/n3 "mspaint"

*inkey(2)

*oshell=createObject("wscript.shell")

*oshell.sendkeys("^{v}")

Endfunc

 

This uses  a transparent filter build with random rectangles with random fills and random strokes and transparency with alpha channel.

Its applied on the image drawn on the canvas with the context('2d') property:

ctx.globalCompositeOperation = "destination-over";

The rectangles contours are romdomly colored  and can be shown or no (choose in the inputbox).

*2* apply a transparent multi rectangles colored filter on any image.

 

Declare Integer BringWindowToTop In user32 Integer

Declare Integer SetWindowText In user32 Integer HWnd, String lpstring

Declare Integer Sleep In kernel32 Integer

Publi apie

apie=Newobject("internetexplorer.application")

apie.Navigate("about:blank")

Sleep(500)

 

With apie

TEXT to m.myvar textmerge noshow

<body topmargin=0 leftmargin=0 bgcolor="black" scroll="no" oncontextmenu="window.close();return false;" >

<canvas id="ycanvas1" width="<<sysmetric(1)>>" height="<<sysmetric(2)>>" ></canvas>

</body>

ENDTEXT

.Document.body.outerhtml=.Document.body.outerhtml+m.myvar

Endwith

 

Local m.xpict

m.xpict=Getpict()

If Empty(m.xpict)

Return .F.

Endi

m.xpict=Strtran(m.xpict,'\','/')

 

Local x0,y0,w,h, gnLower,gnUpper

gnLower=0

gnUpper=Sysmetric(1)-5

x0= Int((gnUpper - gnLower + 1) * Rand( ) + gnLower)

y0=Int((gnUpper - gnLower + 1) * Rand( ) + gnLower)

gnLower=50

gnUpper=200

w=Int((gnUpper - gnLower + 1) * Rand( ) + gnLower)

h=Int((gnUpper - gnLower + 1) * Rand( ) + gnLower)

 

TEXT to m.myvar textmerge noshow

var canvas=document.getElementById("ycanvas1");

canvas.style.background="black";

var ctx = canvas.getContext("2d");

img=new Image();

img.src=' <<xpict>> '  ;

img.onload = function () {

ctx.drawImage(img, 0, 0,canvas.width,canvas.height);

}

ctx.globalCompositeOperation = "destination-over";

 

for (var i = 0; i < 1000; i++) {

var rr=Math.floor(Math.random()*255);

var gg=Math.floor(Math.random()*255);

var bb=Math.floor(Math.random()*255);

var alpha1=0.07; //Math.random();

var col= 'rgba('+rr+','+gg +','+bb+','+alpha1+')';

ctx.fillStyle=col;

 

var min = 0;

var max = <<sysmetric(1)>>;

var x0 = Math.floor(Math.random() * (max - min + 1)) + min;

var y0 = Math.floor(Math.random() * (max - min + 1)) + min;

var w=Math.floor(Math.random() * (200 - 50 + 1)) + min;

var h=Math.floor(Math.random() * (200 - 50 + 1)) + min;

 

ctx.fillRect(x0,y0,w,h);

}

ENDTEXT

 

With apie.Document

x=.createElement("SCRIPT")

x.Id="yscript"

T =.createTextNode(m.myvar)

x.appendChild(T)

.body.appendChild(x)

Endwith

Sleep(2000)

With apie

.menubar=0

.Toolbar=0

.StatusBar=0

 

*if want a noram window

*.width=800

*.height=600

*.top=50

*.left=(sysmetric(1)-.width)/2

 

.fullscreen=1

Local m.mess

TEXT to m.mess noshow

-The picture is captured in clipboard-Run MsPaint and

paste it....save as (png,jpg,gif,bmp...)

-Rightclick or CTRL+F4 to close the window.

ENDTEXT

Messagebox(m.mess,0+32+4096,"",1500)

BringWindowToTop(.HWnd)

SetWindowText(.HWnd, "Html5 canvas image with transparent gradient")

.Visible=.T.

Sleep(700)

ycap()

 

Endwith

 

Retu

 

Function ycap()

Declare Integer keybd_event In Win32API INTEGER, Integer, Integer, Integer

VK_SNAPSHOT = 44 && from the winuser.h

VK_LMENU = 164

KEYEVENTF_KEYUP = 2

KEYEVENTF_EXTENDEDKEY = 1

DoEvents

keybd_event(VK_SNAPSHOT, 1, 0, 0 )

keybd_event(VK_SNAPSHOT, 1, KEYEVENTF_KEYUP, 0 )

DoEvents

 

Inkey(0.5)

*if want to show Mspaint with a pasted picture captured

*_screen.windowstate=1

*run/n3 "mspaint"

*inkey(2)

*oshell=createObject("wscript.shell")

*oshell.sendkeys("^{v}")

Endfunc

 

 

*3*apply a transparent multi circles colored filter on any picture.

*it uses the same code as rectangles but with circles and contrours.

 

Declare Integer BringWindowToTop In user32 Integer

Declare Integer SetWindowText In user32 Integer HWnd, String lpstring

Declare Integer Sleep In kernel32 Integer

Publi apie

apie=Newobject("internetexplorer.application")

apie.Navigate("about:blank")

Sleep(500)

 

With apie

TEXT to m.myvar textmerge noshow

<body topmargin=-20 leftmargin=0 bgcolor="black" scroll="no" oncontextmenu="window.close();return false;" >

<canvas id="ycanvas1" width="<<sysmetric(1)>>" height="<<sysmetric(2)>>" ></canvas>

</body>

ENDTEXT

.Document.body.outerhtml=.Document.body.outerhtml+m.myvar

Endwith

 

 

Local m.xpict

m.xpict=Getpict()

If Empty(m.xpict)

Return .F.

Endi

m.xpict=Strtran(m.xpict,'\','/')

 

Local m.rep,m.xx

m.rep=Inputbox("draw circles contours (yes-no)?","","no")

If !Inlist(m.rep,"yes","no")

m.rep="no"

Endi

If m.rep="yes"

TEXT to m.xx noshow

ctx.lineWidth=1;

rr=Math.floor(Math.random()*255);

gg=Math.floor(Math.random()*255);

bb=Math.floor(Math.random()*255);

alpha1=0.25*Math.random();

col= 'rgba('+rr+','+gg +','+bb+','+alpha1+')';

ctx.strokeStyle=col;

ctx.stroke();

ENDTEXT

Else

m.xx=""

Endi

 

Local x0,y0,w,h, gnLower,gnUpper

gnLower=0

gnUpper=Sysmetric(1)-5

x0= Int((gnUpper - gnLower + 1) * Rand( ) + gnLower)

y0=Int((gnUpper - gnLower + 1) * Rand( ) + gnLower)

gnLower=50

gnUpper=150

w=Int((gnUpper - gnLower + 1) * Rand( ) + gnLower)

*h=Int((gnUpper - gnLower + 1) * Rand( ) + gnLower)

 

TEXT to m.myvar textmerge noshow

var canvas=document.getElementById("ycanvas1");

canvas.style.background="black";

var ctx = canvas.getContext("2d");

img=new Image();

img.src=' <<xpict>> '  ;

img.onload = function () {

ctx.drawImage(img, 0, 0,canvas.width,canvas.height);

}

ctx.globalCompositeOperation = "destination-over";

 

for (var i = 0; i < 1000; i++) {

var rr=Math.floor(Math.random()*255);

var gg=Math.floor(Math.random()*255);

var bb=Math.floor(Math.random()*255);

var alpha1=0.04; //Math.random();

var col= 'rgba('+rr+','+gg +','+bb+','+alpha1+')';

ctx.fillStyle=col;

 

var min = 0;

var max = <<sysmetric(1)>>;

var x0 = Math.floor(Math.random() * (max - min + 1)) + min;

var y0 = Math.floor(Math.random() * (max - min + 1)) + min;

var w=Math.floor(Math.random() * (200 - 50 + 1)) + min;

var h=Math.floor(Math.random() * (200 - 50 + 1)) + min;

 

// draw transparent circle

ctx.beginPath();

ctx.arc(x0, y0, w, 0, 2 * Math.PI, false);

 

ctx.fill();

 

<<m.xx>>

}

ENDTEXT

 

With apie.Document

x=.createElement("SCRIPT")

x.Id="yscript"

T =.createTextNode(m.myvar)

x.appendChild(T)

.body.appendChild(x)

Endwith

Sleep(2000)

*_cliptext=m.myvar

With apie

.menubar=0

.Toolbar=0

.StatusBar=0

*If want a not fullscreen view

*.width=800

*.height=600

*.top=50

*.left=(sysmetic(1)-.width)/2

.fullscreen=1

Local m.mess

TEXT to m.mess noshow

-The picture is captured in clipboard-Run MsPaint and

paste it....save as (png,jpg,gif,bmp...)

-Rightclick or CTRL+F4 to close the window.

ENDTEXT

Messagebox(m.mess,0+32+4096,"",1500)

BringWindowToTop(.HWnd)

SetWindowText(.HWnd, "Html5 canvas image with transparent gradient")

.Visible=.T.

Sleep(700)

ycap()

Endwith

Retu

 

Function ycap()

Declare Integer keybd_event In Win32API INTEGER, Integer, Integer, Integer

VK_SNAPSHOT = 44 && from the winuser.h

VK_LMENU = 164

KEYEVENTF_KEYUP = 2

KEYEVENTF_EXTENDEDKEY = 1

DoEvents

keybd_event(VK_SNAPSHOT, 1, 0, 0 )

keybd_event(VK_SNAPSHOT, 1, KEYEVENTF_KEYUP, 0 )

DoEvents

Inkey(0.5)

*if want to show MSPAINT+picture pasted

*_screen.windowstate=1

*run/n3 "mspaint"

*inkey(2)

*oshell=createObject("wscript.shell")

*oshell.sendkeys("^{v}")

Endfunc

 

This code below is similar to the first above but all is built in the web page.it generates a filter on any image as :

-lineargradient with 7 random colors with transparency in alpha channel

-radialgradient with 7 random colors with transparency in alpha channel

-unique random color with  transparency in alpha channel

can press reset button to change the colors

can save the picture as PNG or print it.

*4*apply a transparent random filter gradient on any image.

* -random lineargradient,random Radial Gradient-random color

Set Safe Off

 

Declare Integer BringWindowToTop In user32 Integer

Declare Integer SetWindowText In user32 Integer HWnd, String lpstring

Declare Integer Sleep In kernel32 Integer

 

Local m.xpict

m.xpict=Getpict()

If Empty(m.xpict)

Return .F.

Endi

 

m.xpict=Strtran(m.xpict,'\','/')

 

TEXT to m.myvar noshow

<!DOCTYPE html>

<html>

<head>

<title>Html5 canvas: Applying filters on image</title>

</head>

<body>

</body>

</html>

ENDTEXT

m.lcdest=Addbs(Sys(2023))+"test.html"

Strtofile(m.myvar, m.lcdest)

Publi apie

apie=Newobject("internetexplorer.application")

apie.Navigate(m.lcdest)

Sleep(500)

 

With apie

TEXT to m.myvar textmerge noshow

 

<body topmargin=0 leftmargin=0 bgcolor="black" scroll="no" oncontextmenu="window.close();return false;" >

<canvas id="ycanvas1" width="<<sysmetric(1)>>" height="<<sysmetric(2)-30>>" ></canvas>

<br>

<center>

<input type="button" id="yb" value="Reset" style="background-color:lime;color:red" onclick="init();">

<input type="button" id="ysave" value="Save As" style="background-color:lime;color:red" onclick="saveImageAs();">

<input type="button" id="yquit" value="Exit" style="background-color:lime;color:red" onclick="window.close();">

</center>

</body>

ENDTEXT

.Document.body.outerhtml=.Document.body.outerhtml+m.myvar

Endwith

 

Local m.rep,m.xx

m.rep=Int(Val(Inputbox("LinearGradient (1) or radialgradient(2) or color(3)","choose gradient/color","1")))

If !Between(m.rep,1,3)

m.rep=1

Endi

 

 

Do Case

Case m.rep=1

TEXT to m.xx noshow

var my_gradient=ctx.createLinearGradient(0,0,canvas.width,0);

my_gradient.addColorStop(0, randomcolor());

my_gradient.addColorStop(0.3,randomcolor());

my_gradient.addColorStop(0.5,randomcolor());

my_gradient.addColorStop(0.7,randomcolor());

my_gradient.addColorStop(1,randomcolor());

ctx.fillStyle=my_gradient;

ENDTEXT

 

Case m.rep=2

TEXT to m.xx noshow

var my_gradient=ctx.createRadialGradient(canvas.width/2,canvas.height/2,50,canvas.width/2,canvas.height/2,canvas.width/2);

my_gradient.addColorStop(0, randomcolor());

my_gradient.addColorStop(0.3,randomcolor());

my_gradient.addColorStop(0.5,randomcolor());

my_gradient.addColorStop(0.7,randomcolor());

my_gradient.addColorStop(1,randomcolor());

ctx.fillStyle=my_gradient;

ENDTEXT

 

Case m.rep=3

TEXT to m.xx textmerge noshow

 

ctx.fillStyle = "rgba(" + Math.round(255 * Math.random()) + ","

+ Math.round(255 * Math.random()) + ","

+ Math.round(255 * Math.random()) + ",0.5)";

ENDTEXT

Endcase

 

TEXT to m.myvar textmerge noshow

function init(){

var canvas=document.getElementById("ycanvas1");

canvas.style.background="black";

var ctx = canvas.getContext("2d");

ctx.fillStyle="000000";

ctx.clearRect(0,0,canvas.width,canvas.height);

 

img=new Image();

img.src=' <<xpict>> ' ;

img.onload = function () {

ctx.drawImage(img, 0, 0,canvas.width,canvas.height);

}

ctx.globalCompositeOperation = "destination-over";

<<m.xx>>

ctx.fillRect(0,0,canvas.width,canvas.height);

}

init();

 

function randomcolor(){

return "rgba(" + Math.round(255 * Math.random()) + ","

+ Math.round(255 * Math.random()) + ","

+ Math.round(255 * Math.random()) + ",0.5)";

}

 

function saveImageAs (){

var c=document.getElementById("ycanvas1");

var d=c.toDataURL("image/png");

alert(d);

var w=window.open('about:blank','','menubar=0, titlebar=0,statusbar=0,width=850,height=650,resizable=1');

w.document.write('<h2 style="background-color:yellow;color:maroon;width:450;">Right click to save image or print<h2><br>'+"<img src='"+d+"' alt='from canvas'/>");

}

ENDTEXT

 

With apie.Document

x=.createElement("SCRIPT")

x.Id="yscript"

T =.createTextNode(m.myvar)

x.appendChild(T)

.body.appendChild(x)

Endwith

Sleep(2000)

 

With apie

.menubar=0

.Toolbar=0

.StatusBar=0

*if want a normal window (adapt dimensions)

*.width=800

*.height=600

*.top=50

*.left=(sysmetric(1)-.width)/2

.fullscreen=1

SetWindowText(.HWnd, "Html5 canvas image with transparent gradient")

 

Local m.mess

TEXT to m.mess noshow

-Right click or CTRL+F4 to close the fullscreen window (or simply click 'exit' button!

-can change the random gradients(linear,radial,or colors) by the button 'reset'

-can save the image as PNG (or pint it).click the button 'save'

 

ENDTEXT

Messagebox(m.mess,0+32+4096,2000)

BringWindowToTop(.HWnd)

.Visible=.T.

Endwith

Retu

 

 

 

 

 

 

These images are from Taghit and Brezina two  algerian sahara oasis i like and visit too.Gradients colors can be changed in code.
These images are from Taghit and Brezina two  algerian sahara oasis i like and visit too.Gradients colors can be changed in code.
These images are from Taghit and Brezina two  algerian sahara oasis i like and visit too.Gradients colors can be changed in code.
These images are from Taghit and Brezina two  algerian sahara oasis i like and visit too.Gradients colors can be changed in code.
These images are from Taghit and Brezina two  algerian sahara oasis i like and visit too.Gradients colors can be changed in code.
These images are from Taghit and Brezina two  algerian sahara oasis i like and visit too.Gradients colors can be changed in code.
These images are from Taghit and Brezina two  algerian sahara oasis i like and visit too.Gradients colors can be changed in code.
These images are from Taghit and Brezina two  algerian sahara oasis i like and visit too.Gradients colors can be changed in code.
These images are from Taghit and Brezina two  algerian sahara oasis i like and visit too.Gradients colors can be changed in code.
These images are from Taghit and Brezina two  algerian sahara oasis i like and visit too.Gradients colors can be changed in code.
These images are from Taghit and Brezina two  algerian sahara oasis i like and visit too.Gradients colors can be changed in code.
These images are from Taghit and Brezina two  algerian sahara oasis i like and visit too.Gradients colors can be changed in code.
These images are from Taghit and Brezina two  algerian sahara oasis i like and visit too.Gradients colors can be changed in code.
These images are from Taghit and Brezina two  algerian sahara oasis i like and visit too.Gradients colors can be changed in code.
These images are from Taghit and Brezina two  algerian sahara oasis i like and visit too.Gradients colors can be changed in code.
These images are from Taghit and Brezina two  algerian sahara oasis i like and visit too.Gradients colors can be changed in code.

These images are from Taghit and Brezina two algerian sahara oasis i like and visit too.Gradients colors can be changed in code.

To be informed of the latest articles, subscribe:
Comment on this post