Construire un éditeur d'image Canvas avec Canvas

Nous n'allons pas nous déchaîner avec cela, nous n'avons tout simplement pas le temps, mais nous verrons à quel point il est facile de faire des choses comme la rotation, le redimensionnement, la traduction et même la manipulation subtile des couleurs. Ne vous leurrez pas, nous allons finir avec un équivalent de Photoshop, bien que ce soit théoriquement possible, mais étant donné que nous ne travaillons que dans les limites d'un navigateur aussi complexe, je pense toujours que c'est assez remarquable..

Ce tutoriel comprend un screencast disponible pour les membres Tuts + Premium.


Ce dont vous aurez besoin pour ce tutoriel

Pour produire localement une version de travail de la démo, vous devez utiliser un navigateur Webkit, tel que Safari, Chrome ou Opera. La démonstration fonctionnera sous Firefox, mais elle devra être exécutée sur un serveur Web pour que la plupart des fonctionnalités fonctionnent. Ne pensez même pas à utiliser IE; seule la version 9 aborde même le support de l'élément canvas, et pour tout dire, je ne ferais même pas confiance à IE9 pour restituer correctement le code et les fonctionnalités.


Commencer

Le HTML sous-jacent est vraiment assez trivial; Tout ce dont nous avons besoin pour la structure de l'éditeur sont les éléments de base suivants:

    Éditeur d'image sur toile     
Sauvegarder Tourner à gauche Tourner à droite Redimensionner B & W Sépia

Enregistrer la page sous image-editor.html. Outre les éléments HTML standard constituant le squelette de la page, nous avons une feuille de style personnalisée, que nous ajouterons dans un instant, et une feuille de style fournie par jQuery UI. Au bas de la page, juste avant la fermeture balise, nous avons une référence à jQuery (la version actuelle est 1.4.4), une référence à jQuery UI (version actuelle 1.8.7) et une balise de script vide dans laquelle nous allons insérer le code donne à l'éditeur sa fonctionnalité.

Les composants de l'interface utilisateur jQuery que nous allons utiliser dans cet exemple sont redimensionnables et dialogués, et le thème est ui-lightness..

Les éléments visibles sur la page sont assez basiques; nous avons un contenant externe

élément, dans lequel résident deux
éléments. Le premier contient le élément que nous allons utiliser pour manipuler notre image. La seconde contient une barre d’outils de boutons qui seront utilisés pour effectuer les manipulations. Du identifiant attributs donnés à chaque bouton, il devrait être assez évident de voir ce que chaque bouton fait.


Ajout des styles

Comme le HTML, le CSS utilisé est extrêmement simple et comprend les éléments suivants:

#imageEditor width: 482px; marge: auto; rembourrage: 20px; bordure: solide 1px # 4b4b4b; -moz-border-radius: 8px; -webkit-border-radius: 8px; border-radius: 8px; couleur de fond: #ababab;  #editorContainer display: block; largeur: 480px; hauteur: 480px;  #editor display: block; marge: 0 20px 20px 0; bordure: solide 1px # 4b4b4b;  #barre d'outils display: block; marge: 20px 0 0;  #barre d'outils a marge-droite: 10px; contour: aucun; couleur: # 4b4b4b;  #resizer border: 2px dashed # 000;  #tip padding: 5px; marge: 0; bordure: 1px solide # 000; -moz-border-radius: 3px; -webkit-border-radius: 3px; border-radius: 3px; position: absolue; couleur d'arrière-plan: #fff; couleur de fond: rgba (255,255,255, 0,3); -moz-box-shadow: 1px 1px 1px rgba (0,0,0,0,5); -webkit-box-shadow: 1px 1px 1px rgba (0,0,0,0,5); boîte-ombre: 1px 1px 1px rgba (0,0,0,0,5); 

Enregistrer ceci sous image-editor.css dans le même répertoire que la page HTML. Il n'y a rien de vraiment remarquable ici, principalement les styles de l'éditeur et ses éléments constitutifs, illustrés dans la capture d'écran ci-dessous:



Screencast complet



La partie amusante

Il ne reste plus qu'à ajouter le code permettant à l'éditeur de fonctionner. Commencez par ajouter le code ci-dessous au vide > élément en bas de page:

(function ($) // récupère le canevas et le contexte var editor = document.getElementById ("editor"), context = editor.getContext ("2d"), // crée / charge l'image image = $ ("", src:" img / graffiti.png ", chargement: function () context.drawImage (this, 0, 0);), // plus de code à suivre ici?) (jQuery);

Tout d’abord, nous plaçons tout notre code dans une fermeture et aliasons l’objet jQuery en tant que $ personnage. Je me rends compte que jQuery s'appelle automatiquement le caractère $ pour nous, cependant, dans certaines situations, cela peut entraîner des conflits avec un autre code pouvant être utilisé lorsque notre code est implémenté par d'autres.

C'est également la méthode recommandée pour créer des plugins. Par conséquent, le fait de le faire chaque fois que jQuery est utilisé permet de revenir plus rapidement et plus facilement et de transformer le code en plugin si nécessaire. Je trouve simplement plus pratique d'écrire tout mon code jQuery dans une fermeture comme celle-ci. Il présente également d'autres avantages, tels que la suppression d'une dépendance à l'égard de variables globales - toutes les variables que nous créons seront masquées de manière sûre à tout autre code en dehors de la clôture dans la plupart des situations..

Pour travailler avec le canevas, nous devons obtenir une référence à son contexte. Ceci est un objet représentant la surface de la toile sur laquelle plus des méthodes pour travailler avec la toile sont appelées. Quelques méthodes peuvent être appelées directement sur l'objet canvas, mais la plupart sont appelées sur l'objet context.

Obtenir le contexte est un processus en deux étapes. nous obtenons d’abord une référence à la l'élément lui-même en utilisant le JavaScript standard document.getElementById () méthode, on appelle alors le getContext () method sur la toile (c’est une de ces méthodes qui peut être appelée directement sur l’élément canvas, et pour cause!), en spécifiant 2d comme le contexte. À l’heure actuelle, le 2d est le seul contexte qui existe largement, même si à l’avenir nous pourrons peut-être espérer travailler avec des contextes 3D..

Les objets canvas et context sont stockés dans des variables de niveau supérieur (l'équivalent des variables globales si nous ne travaillions pas dans une fermeture), de sorte que toutes les fonctions que nous définissons puissent les utiliser..

Suite à ces deux variables, nous en créons une autre, appelée image. Nous utilisons ici jQuery pour créer rapidement et sans effort un nouvel élément d'image. Nous avons mis le src d’une image (un exemple, une image exempte de droits est incluse dans le téléchargement du code) de sorte que nous puissions travailler avec en charge gestionnaire d'événement qui peint simplement l'image sur le canevas que l'image a chargé. Lors de l'utilisation du canevas, il est important de s'assurer que toutes les images utilisées sont entièrement chargées avant de les ajouter au canevas..

L'image est peinte sur la toile à l'aide du bouton drawImage () méthode, qui est appelée sur le le contexte objet. Cette méthode prend trois arguments (elle peut éventuellement en prendre plus, comme nous le verrons plus loin dans l'exemple); ces arguments sont l'image à utiliser (référée à l'aide de la ce mot clé), le X position sur la toile pour commencer à dessiner l'image, et le y position sur la toile pour commencer à dessiner l'image. L'image d'exemple est la taille exacte de la toile dans cet exemple, et par souci de simplicité, elle est complètement carrée..

Nous sommes maintenant prêts à ajouter du code supplémentaire à ce stade. Il y a une virgule de fin après l'image que nous avons créée. Le prochain morceau de code ajouté sera donc également une variable..


Ajout de fonctionnalités à la barre d'outils

Ensuite, nous devons ajouter du code pour gérer les boutons de la barre d’outils. Nous pourrions simplement ajouter une série de gestionnaires de clic, un pour chaque bouton que nous souhaitons ajouter. Bien que facile à faire, cela ne serait pas extrêmement efficace et ne serait pas incroyablement évolutif.

Idéalement, nous voulons une fonction principale unique qui gère un clic sur n’importe quel bouton et appelle la fonction correcte. Heureusement, cela est également très facile. Ajoutez le code suivant directement après l'image que nous venons de créer:

// fonctions de la barre d'outils tools = ; $ ("# barre d'outils"). enfants (). cliquez sur (fonction (e) e.preventDefault (); // appelez les outils de fonction appropriés [this.id] .call (this););

C'est aussi simple que ça. Voyons ce que fait ce code. La dernière variable de niveau supérieur que nous créons est appelée outils et contient un objet vide (à ce stade). Les fonctions de chaque bouton seront toutes placées dans cet objet, comme nous le verrons bientôt.

Nous ajoutons ensuite un seul Cliquez sur gestionnaire, attaché à tous les enfants de l'élément avec l'identifiant barre d'outils (un de

éléments dans le HTML sous-jacent).

Au sein de cette fonction de gestion des clics, nous arrêtons d’abord le comportement par défaut du navigateur, qui consiste à suivre le lien (cela évite le comportement indésirable de «saut en haut» parfois présenté lors de l’utilisation standard. des éléments comme des boutons).

Enfin nous appliquons le JavaScript appel() méthode à la fonction contenue dans la propriété de la outils objet qui correspond à la identifiant attribut du lien sur lequel vous avez cliqué. Comme tout ce dont nous avons besoin depuis le lien cliqué, c’est sa identifiant attribut, on peut utiliser le standard ce mot-clé sans l'envelopper dans un objet jQuery. le appel() méthode nécessite que le ce mot-clé est également passé comme argument.

Maintenant, si nous ajoutons une fonction à l'objet tools sous la propriété enregistrer, chaque fois que l'on clique sur le bouton de la barre d'outils avec le identifiant save, la fonction sera appelée. Il ne reste donc plus qu’à ajouter une fonction à chacun de nos boutons de la barre d’outils..


Sauvegarde de l'image modifiée

Nous allons commencer par la fonction de sauvegarde car elle est plutôt petite et facile. Ajoutez le code suivant au outils objet:

// sortie vers  save: function () var saveDialog = $ ("
") .appendTo (" body "); $ ("", src: editor.toDataURL ()). appendTo (saveDialog); saveDialog.dialog (redimensionnable: false, modal: true, titre:" Cliquez avec le bouton droit de la souris et choisissez "Enregistrer l'image sous" ", width: editor. largeur + 35);,

La première chose que notre fonction fait est de créer un nouveau

élément et l'ajouter à la de la page. Cet élément sera utilisé avec le composant de dialogue de jQuery UI pour produire une boîte de dialogue modale..

Ensuite, nous créons un nouvel élément d'image. cette fois nous mettons c'est src à une représentation codée en base 64 de tout ce qui est contenu dans la toile. Cette action est effectuée en utilisant le toDataURL () méthode, qui est d'ailleurs une autre méthode appelée directement sur l'élément canvas. Une fois créée, l'image est ajoutée à la

élément créé à l'étape précédente.

Enfin, nous initialisons le composant dialogue. cela fait en utilisant le dialogue() method, une méthode ajoutée par jQuery UI. Un littéral d'objet est passé à la dialogue() méthode qui nous permet de définir ses différentes options de configuration. Dans ce cas, nous configurons la boîte de dialogue de sorte qu'elle ne soit pas redimensionnable et modale (une superposition sera appliquée au reste de la page tant que la boîte de dialogue sera ouverte). Nous définissons également le titre de la boîte de dialogue sur une chaîne donnant des instructions sur la procédure à suivre pour enregistrer l’objet. La boîte de dialogue est suffisamment grande pour contenir l’image en définissant sa largeur sur la largeur de l’élément canvas plus 35 pixels.


Rotation

Une fonctionnalité commune des éditeurs d'image est la possibilité de faire pivoter un élément. L'utilisation de la fonctionnalité de toile intégrée permet de l'implémenter facilement dans notre éditeur. Ajoutez les fonctions suivantes après la fonction de sauvegarde:

rotation: function (conf) // sauvegarde l'image courante avant de faire pivoter $ ("", src: editor.toDataURL (), load: function () // fait pivoter le canevas context.clearRect (0, 0, editor.width, editor.height); context.translate (conf.x, conf.y) ; context.rotate (conf.r); // redessine l'image sauvegardée context.drawImage (this, 0, 0););, rotationL: fonction () var conf = x: 0, y: editor. height, r: -90 * Math.PI / 180; tools.rotate (conf);, rotationR: fonction () var conf = x: editor.width, y: 0, r: 90 * Math.PI / 180; tools.rotate (conf);,

Nous avons donc ajouté trois nouvelles fonctions. une fonction de rotation principale, puis une fonction pour les boutons de rotation gauche et droit de la barre d’outils. le rotationL () et rotationR () fonctions chaque chacun juste construire un objet de configuration personnalisé et ensuite appeler le maître tourner() fonction, en passant dans l'objet de configuration. C'est le maître tourner() fonction qui effectue réellement la rotation. Un point important à noter est que c'est la toile que nous faisons pivoter, pas l'image sur la toile..

L'objet de configuration que nous créons dans le rotationL () et rotationR () les fonctions sont très simples; il contient trois propriétés - X, y et r. Les propriétés X et y se référer à la quantité de traduction qui est nécessaire et r est le montant de la rotation. Chaque clic sur un bouton de rotation fera pivoter l'image de plus ou moins 90 degrés.

dans le rotationL () Pour que l’image reste visible une fois que la toile a été tournée, nous devons traduire la zone de travail à la même distance que la hauteur de la zone sur l’axe vertical. La rotation vers la gauche est classée comme rotation négative car elle est anti-horaire. Lors du calcul de l'angle de rotation, nous ne pouvons pas utiliser de degrés, nous devons convertir 90 degrés (ou -90 degrés dans ce cas) en radians. Ceci est facile et nécessite la formule suivante:

Le nombre de degrés multiplié par Pi divisé par 180

le rotationR () la fonction est tout aussi simple, cette fois nous traduisons le canevas sur l'axe horizontal au lieu de l'axe vertical et utilisons un nombre positif pour la rotation dans le sens des aiguilles d'une montre.

Dans le maître tourner() Nous devons à nouveau saisir une copie de l’image en cours sur le canevas en créant un nouvel élément d’image avec jQuery et en définissant son src au résultat de la toDataURL () méthode à nouveau. Cette fois, nous voulons dessiner l’image sur la toile une fois que celle-ci a été tournée, nous ajoutons un en charge gestionnaire d'événement à l'image.

Une fois l'image chargée, effacez d'abord la toile à l'aide du bouton clearRect () méthode. Cette méthode prend quatre arguments; les deux premiers arguments sont les X et y coordonnées pour commencer le nettoyage. Le troisième et le troisième sont la taille de la zone à nettoyer. Nous voulons vider le canevas entier pour commencer à 0,0 (le coin supérieur gauche du canevas) et effacer toute la largeur et la hauteur du canevas..

Une fois que nous avons nettoyé la toile, nous la traduisons (déplacez-la essentiellement) à l'aide du Traduire() méthode de transformation. Nous le traduirons soit sur toute la hauteur, soit sur toute la largeur de la toile selon que le rotationL () ou rotationR () la fonction a initié la rotation. La traduction du canevas est nécessaire car, par défaut, la rotation a lieu en bas à droite du canevas et non au milieu.

Nous pouvons ensuite faire pivoter la toile, puis redessiner l'image sur la toile. Même si nous attirons la même image sur le canevas, celui-ci a été pivoté de manière à ce que l'image le soit automatiquement. De nouveau, nous pouvons nous référer à l’image à transmettre au drawImage () méthode comme ce parce que nous sommes à l'intérieur du gestionnaire de chargement pour l'image et que jQuery s'assure que cela se réfère à l'image. La capture d'écran suivante montre l'image pivotée une fois vers la gauche:



Redimensionner l'image

Le redimensionnement de l’image est notre interaction la plus complexe et la fonction requise pour le faire est assez grande, même si le redimensionnement de la zone de travail elle-même est assez trivial. Ajoutez la fonction suivante à l’objet tools après les fonctions de rotation que nous venons de regarder:

resize: function () // créer un objet redimensionnable sur la toile var coords = $ (éditeur) .offset (), resizer = $ ("
", id:" resizer "). css (position:" absolute ", gauche: coords.left, haut: coords.top, largeur: editor.width - 1, hauteur: editor.height - 1). appendTo ("body"); var resizeWidth = null, resizeHeight = null, xpos = editor.offsetLeft + 5, ypos = editor.offsetTop + 5; resizer.resizable (aspectRatio: true, maxWidth: editor.width - 1, maxHeight : editor.height - 1, redimensionner: function (e, ui) resizeWidth = Math.round (ui.size.width); resizeHeight = Math.round (ui.size.height); // info-bulle pour afficher une nouvelle taille string = "Nouvelle largeur:" + resizeWidth + "px,
nouvelle hauteur: "+ resizeHeight +" px "; if ($ (" # tip "). length) $ (" # tip "). html (string); else var tip = $ (" ", id : "tip", html: string). css (left: xpos, en haut: ypos). appendTo ("body");, arrêtez: function (e, ui) // confirmez le redimensionnement, puis faites il var confirmDialog = $ ("
", html:" L'image sera redimensionnée à "+ resizeWidth +" px large, et "+ resizeHeight +" px haut.
Continuer? "); // init confirmer le dialogue confirmDialog.dialog (redimensionnable: false, modal: true, titre:" Confirmer le redimensionnement? ", Boutons: Annuler: function () // ranger $ (this). dialogue ("fermer"); resizer.remove (); $ ("# astuce"). remove ();, Oui: function () // ranger $ (this) .dialog ("fermer"); resizer .remove (); $ ("# tip"). remove (); $ ("", src: editor.toDataURL (), load: function () // supprime l’ancienne image context.clearRect (0, 0, editor.width, editor.height); // redimensionne la toile editor.width = resizeWidth; editor .height = resizeHeight; // redessine l'image sauvegardée context.drawImage (this, 0, 0, resizeWidth, resizeHeight);););,

Voyons donc les étapes requises par notre fonction de redimensionnement. Tout d'abord, nous avons besoin d'un moyen d'indiquer à l'utilisateur la taille de l'image redimensionnée. L'utilisateur a également besoin d'un moyen de définir la nouvelle taille. Nous voulons ensuite confirmer si l'utilisateur souhaite appliquer la nouvelle taille et, le cas échéant, appliquer la nouvelle taille. La nouvelle fonction fait tout, voyons comment.

Nous obtenons d’abord les coordonnées sur la page de l’élément canvas à l’aide de jQuery décalage() méthode, de sorte que nous sachions où positionner l’élément redimensionnable. Nous créons ensuite un nouveau

élément, qui deviendra redimensionnable, et lui donnera un identifiant de redimensionner afin que nous puissions facilement nous y référer. Nous avons également défini certaines propriétés de style du nouvel élément afin de le positionner sur le canevas. Une fois que ces styles sont définis, nous l’ajoutons à la de la page. Le redimensionnable apparaîtra comme une bordure en pointillé autour de l'intérieur de la toile, comme indiqué ci-dessous:


Ensuite, nous initialisons deux autres variables, mais définissons leurs valeurs sur nul pour le moment. Ceux-ci seront utilisés pour stocker la largeur et la hauteur auxquelles le redimensionnable est changé lorsqu'il est redimensionné. Ces variables seront renseignées et utilisées plus tard dans la fonction. le xpos et Ypos les variables sont utilisées pour positionner une info-bulle que nous allons créer dans un moment. Ils positionnent l'info-bulle à 5 pixels du bord gauche et du bord supérieur du canevas..

Ensuite, nous initialisons le redimensionnable à l’aide de jQuery UI redimensionnable () méthode. Nous configurons le redimensionnable pour que son format d'image soit verrouillé; notre image est carrée, nous voulons donc qu'elle reste carrée quelle que soit la taille à laquelle elle est redimensionnée. Nous nous assurons également que la taille de l'image ne peut pas être augmentée, de sorte que la qualité de l'image soit conservée. Si l'image était agrandie au lieu d'être réduite, elle deviendrait bloc. le largeur maximale et hauteur maximum Les options de configuration permettent de réduire la taille de l'image. Les deux sont réglés sur la largeur et la hauteur actuelles de la toile..

Le composant redimensionnable a des gestionnaires d’événements personnalisés auxquels nous pouvons affecter des fonctions qui seront exécutées lors du déclenchement de ces événements personnalisés. Nous utilisons deux de ces gestionnaires d’événements pour cet exemple; redimensionner, qui sera déclenché chaque fois que le redimensionnable est redimensionné, et Arrêtez qui est déclenché une fois que le redimensionnable a fini d'être redimensionné.

La fonction de redimensionnement peut recevoir deux arguments; le premier est un objet événement, que nous n'avons pas besoin d'utiliser dans cet exemple, mais qui doit être déclaré afin de pouvoir utiliser le deuxième argument, ce dont nous avons besoin. Le deuxième argument est un objet contenant des informations utiles sur le redimensionnable, y compris la taille à laquelle il a été modifié. La première chose que nous faisons dans cette fonction est d’attribuer la nouvelle taille du redimensionnable à notre resizeWidth et resizeHeight variables utilisant les propriétés du ui objet que la fonction reçoit.

La dernière chose que cette fonction fait est de créer une info-bulle qui indique à l’utilisateur quelle est la taille du fichier redimensionnable. Si cette info-bulle existe déjà, nous n'avons pas besoin de la recréer et nous pouvons simplement définir son texte interne sur une chaîne indiquant la taille actuelle du redimensionnable. Si l'info-bulle n'existe pas déjà, comme lors du premier redimensionnement, nous la créons à partir de zéro. L'info-bulle est positionnée à l'aide du xpos et Ypos que nous avons créé plus tôt. La chaîne est construite à partir de zéro chaque fois que le redimensionnable change de taille. L'info-bulle va ressembler à ceci:


La fonction stop, qui est exécutée une fois à la fin de l'interaction de redimensionnement, crée d'abord un nouvel élément de boîte de dialogue qui vérifie que le visiteur souhaite appliquer la nouvelle taille à la zone de dessin. Une fois encore, la boîte de dialogue est configurée de sorte qu'elle ne soit pas redimensionnable et qu'elle soit modale. Nous ajoutons également quelques boutons à cette boîte de dialogue. Le premier est un Annuler bouton, qui permet au visiteur de revenir sur l'opération de redimensionnement sans appliquer la nouvelle taille. Tout ce que nous faisons ici est un peu de ménage, en supprimant la boîte de dialogue, le redimensionnable, et l'info-bulle.

Nous créons également un Oui bouton qui applique la nouvelle taille. Nous effectuons également ici les mêmes tâches d’entretien, mais pour appliquer la nouvelle taille, nous créons à nouveau une nouvelle image, comme nous l’avons déjà fait à plusieurs reprises. Il est extrêmement facile de définir la nouvelle taille de la toile. nous fournissons simplement les valeurs pour lesquelles le redimensionnable a été modifié en propriétés de largeur et de hauteur de l'élément canvas. Voici la boîte de dialogue qui apparaît de la même manière que la boîte de dialogue de sauvegarde précédente, mais avec un contenu différent:



Modification des valeurs RVB de pixels individuels

J'ai dit plus tôt que nous avons un contrôle complet au niveau des pixels du contenu de l'élément canvas, donc nos deux dernières fonctions de bouton de barre d'outils le feront exactement. La première fonction est utilisée pour convertir l'image en niveaux de gris, la seconde modifie l'image en sépia. Nous allons d'abord examiner la fonction de niveaux de gris:

niveaux de gris: function () // récupérer les données d'image var imgData = context.getImageData (0, 0, editor.width, editor.height), pxData = imgData.data, length = pxData.length; pour (var x = 0; x < length; x+=4)  //convert to grayscale var r = pxData[x], g = pxData[x + 1], b = pxData[x + 2], grey = r * .3 + g * .59 + b * .11; pxData[x] = grey; pxData[x + 1] = grey; pxData[x + 2] = grey;  //paint grayscale image back context.putImageData(imgData, 0, 0); ,

La première chose que cette fonction doit faire est d’obtenir les données de pixel actuelles du canevas. Nous utilisons le getImageData () méthode pour le faire. Cette méthode accepte quatre arguments, identiques à ceux de clearRect () méthode que nous avons examinée plus tôt - les deux premiers arguments sont les X et y les positions pour commencer à collecter des données et les troisième et quatrième sont la largeur et la hauteur de la zone à obtenir. Nous voulons la totalité de la toile, nous commençons donc à 0,0 (en haut à gauche) et continuons pour la largeur et la hauteur de la toile. L'objet résultant renvoyé par la méthode est stocké dans la imgData variable.

L'objet stocké dans cette variable a une propriété appelée Les données; au sein de cette propriété est un tableau contenant le r g b et des valeurs alpha pour chaque pixel du canevas, le premier élément du tableau contiendra le r valeur du premier pixel, le deuxième élément contient le g valeur du premier pixel, le troisième contient le b valeur du premier pixel et le quatrième élément contient la valeur alpha du premier pixel. Ce tableau est incroyablement grand; une image de 480 x 480 pixels contient 230400 pixels et nous avons quatre éléments pour chaque pixel. Cela rend le tableau un total de 921600 éléments de longueur! Cette longueur est également stockée pour être utilisée dans pour boucle que nous définissons ensuite.

La boucle for est un peu différente de celle des boucles habituelles. Rappelez-vous que le tableau peut être organisé en blocs discrets de 4 éléments, chaque élément d’un bloc faisant référence aux composants individuels rgba, nous allons donc parcourir le tableau quatre éléments à la fois. A chaque itération, nous obtenons chaque composant de pixel et utilisons ensuite la formule r * .3 + g * .59 + b * .11 convertir chacun en niveaux de gris. Nous enregistrons ensuite le composant pixel converti dans son élément de tableau d'origine..

Une fois que nous avons parcouru tout le tableau, nous pouvons écrire le contenu du tableau sur la toile, en remplaçant chaque pixel d'origine par son nouveau pendant en niveaux de gris à l'aide de la commande putImageData () méthode, qui fait simplement le contraire de getImageData ().

La fonction de ton sépia est identique à la fonction de niveaux de gris, sauf que nous utilisons une formule différente pour convertir chaque r g b composant à ton sépia:

sépia: function () // récupère les données d'image var imgData = context.getImageData (0, 0, editor.width, editor.height), pxData = imgData.data, length = pxData.length; pour (var x = 0; x < length; x+=4)  //convert to grayscale var r = pxData[x], g = pxData[x + 1], b = pxData[x + 2], sepiaR = r * .393 + g * .769 + b * .189, sepiaG = r * .349 + g * .686 + b * .168, sepiaB = r * .272 + g * .534 + b * .131; pxData[x] = sepiaR; pxData[x + 1] = sepiaG; pxData[x + 2] = sepiaB;  //paint sepia image back context.putImageData(imgData, 0, 0); 

Voici une photo de l'image une fois qu'elle a été convertie en ton sépia:



Conclusion

Dans ce didacticiel, nous avons vu comment transformer le canevas en un éditeur d’images puissant qui nous donne certaines des fonctionnalités des éditeurs d’images de base, basés sur des applications, avec lesquels nous sommes familiers. Cet exemple pourrait facilement être étendu pour ajouter d'autres fonctionnalités, telles que le rognage et le dessin avec un outil au crayon, bien que je vous laisse l'ajout de cette fonctionnalité. Merci d'avoir lu.