Gestion des images avec eFORTH pour le web
publication: 21 mars 2023 / mis à jour 19 avril 2023
Chargement et affichage des images
La gestion des images est réalisée à partir du mot drawImage
. ce mot n'étant pas défini dans eFORTH, voici comment
le créer dans le vocabulaire web
:
web definitions JSWORD: drawImage { a n x y } let img = new Image(); img.addEventListener('load', function() { context.ctx.drawImage(img, x, y); }, false); img.src = GetString(a, n); ~ forth definitions
Voici une image, au format GIF, qui va nous servir pour ces premiers tests. Vous pouvez récupérer cette image par clic-droit et Enregistrer l'image sous....
Et voici comment utiliser drawImage
pour l'intégrer à canvas:
600 constant ctxWidth 300 constant ctxHeight web gr ctxWidth ctxHeight window s" greenPencil.gif" 20 10 drawImage
Pour centrer cette image, il faut récupérer ses dimensions. Pour ce faire, définissons ce mot:
web definitions JSWORD: imageSize { a n -- w h } let img = new Image(); img.src = GetString(a, n); if(img.complete){ return [img.naturalWidth, img.naturalHeight]; } ~ forth definitions
Voici un code non optimisé montrant comment calculer la position de l'image pour qu'elle soit positionnée au centre de notre espace délimité par canvas.
forth definitions 600 constant ctxWidth 300 constant ctxHeight web gr ctxWidth ctxHeight window 0 value imageWidth 0 value imageHeight s" greenPencil.gif" imageSize to imageHeight to imageWidth s" greenPencil.gif" ctxWidth imageWidth - 2/ ctxHeight imageHeight - 2/ drawImage
Affichage et découpage d'une image au format jpg
Le mot drawImage sait afficher divers format d'images: gif, png, jpg, svg. Voyons comment afficher et découper une image au format jpg. Mais avant de voir en détail ce découpage d'image, définissons ces mots:
web definitions JSWORD: getImageData { addr len x y w h } var myString = GetString(addr, len); const imageData = context.ctx.getImageData(x, y, w, h); Object.assign(context.ctx, {[myString]:imageData}); ~ \ usage: \ s" motorhome" 20 30 100 200 getImageData \ create copie from canvas content, named "motorhome" JSWORD: putImageData { addr len x y } var myString = "context.ctx." + GetString(addr, len); const imageData = eval(myString); console.info(imageData); context.ctx.putImageData(imageData, x, y); ~ \ usage: \ s" motorhome" 300 30 putImageData \ createin dictionnay and save part of image \ execuction of x ydisplay saved part of image : getImage: ( comp: x y w h --| exec: x y create >r >r >r >r latestxt dup , >name r> r> r> r> getImageData does> -rot >r >r @ >name r> r> putImageData ; forth definitions)
Fonctionnement de ces trois nouvelles définitions:
getImageData
récupère une partie d'image déjà affichée et stocke les données de cette partie d'image dans un objet Javascript;putImageData
affiche à la position x y une partie d'image précédemment stockée pargetImageData
et désignée par son nom d'objet Javascript;getImage:
crée un mot dans le vocabulaire FORTH qui pointe vers l'objet Javascript de même nom et stockant une partie d'image. L'exécution de ce mot, précédé des coordonnées x y affiche le contenu de cette partie d'image.
Voici l'utilisation du mot getImage:
:
: imgCCar ( -- addr len )
s" ccar.jpg"
;
web gr
ctxWidth ctxHeight window
imgCCar 5 5 drawImage
500 ms
30 5 80 232 getImage: motorhome
380 5 motorhome
465 5 motorhome
Notre image a comme nom ccar.jpg. Le mot imgCCar
est donc une sorte de constante de chaine alphanumérique.
La séquence de code 30 5 80 232 getImage: motorhome
va copier une partie de l'image affichée dans canvas, à partir de
x et y (30 5) et de 80 pixels de large et 232 pixels de haut. Le mot getImage:
crée le mot motorhome
.
L'exécution de motorhome
précédé des coordonnées x y d'affichage affiche la partie d'image copiée au moment de
créer motorhome
.
Tester la couleur d'un pixel image
Pour tester la couleur d'un pixel, on définit une variante du mot getImageData
, mais qui teste
seulement un pixel dans l'espace graphique canvas:
web definitions
\ get pixel color at x y
JSWORD: getPixelColor { x y -- c }
var pixel = context.ctx.getImageData(x, y, 1, 1);
console.info(pixel);
return pixel.data[0]*256*256 + pixel.data[1]*256 + pixel.data[2];
~
forth definitions
Voici un cas d'école. Tracer trois boites rectangulaires. L'astuce, ici, c'est de tracer ces trois boites en bleu, mais avec une couleur bleur adaptée à chaque boite:
$0000ff constant colorBox1 $0001ff constant colorBox2 $0100ff constant colorBox3 web gr ctxWidth ctxHeight window colorBox1 color! 10 10 100 50 fillRect colorBox2 color! 120 10 300 120 fillRect colorBox3 color! 400 140 180 120 fillRect
Voici une définition testBoxes
qui va tester le pixel pointé par la souris. La couleur testée permet de savoir quelle
boite est pointée:
: waitButtonDown ( -- )
begin
button 0=
until
;
: testBoxes
begin
button if
getMousePosition getPixelColor
case
page
colorBox2 of ." BOX 2 selected" cr endof
colorBox3 of ." BOX 3 selected" cr endof
colorBox1 of ." BOX 1 selected" cr endof
endcase
200 ms
then
key? until
;
." click on any blue box / space to STOP" cr
testBoxes
Voici la définition de getMousePosition
qui n'est pas défini dans le vocabulaire web d'origine:
web definitions \ The word mouse delivers the position of the mouse pointer from the origin x y (0, 0) \ of the HTML page and not from the origin of the canvas. \ The word getMousePosition retrieves and recalculates the relative position of the \ mouse pointer from the origin of the canvas. JSWORD: getMousePosition { -- mousex mousey } var offset = {x: 0, y: 0}; var node = context.ctx.canvas; while (node) { offset.x += node.offsetLeft; offset.y += node.offsetTop; node = node.offsetParent; } return [context.mouse_x-offset.x, context.mouse_y-offset.y]; ~ forth definitions
Cette définition est à utiliser en remplacement de mouse
.
Legal: site web personnel sans commerce / personal site without seling