Construiți un editor de canvas cu panza

Nu vom merge în sălbăticie, nu este timp, dar vom vedea cât de ușor este să faci lucruri precum rotirea, redimensionarea, traducerea și chiar manipularea subtilă a culorilor. Nu vă înșelați că vom termina cu un Photoshop, deși acest lucru este posibil în mod teoretic, dar având în vedere că lucrăm în limitele a ceva mai complexe decât un browser, personal încă mai cred că este destul de remarcabil.

Acest tutorial include un screencast disponibil pentru membrii Tuts + Premium.


Ce veți avea nevoie pentru acest tutorial

Pentru a produce o versiune de lucru a demo-ului local, va trebui să utilizați un browser bazat pe Webkit, cum ar fi Safari sau Chrome sau Opera. Demo-ul va funcționa în Firefox, dar va trebui să fie rulat printr-un server web pentru cea mai mare parte a funcționalității de lucru. Nu gândiți nici măcar la utilizarea IE; numai versiunea 9 abordează chiar și suportul pentru elementul de panza și, pentru a fi sincer, nu aș avea nici măcar încredere în IE9 pentru a face corect codul și funcționalitatea.


Noțiuni de bază

HTML-ul subiacent este într-adevăr destul de banal; tot ceea ce avem nevoie pentru structura editorului sunt următoarele elemente de bază:

    Canvas Image Editor     
Salvați Rotire Stânga Rotire Dreapta Redimensionați Sepia B & W

Salvați pagina ca image-editor.html. În afară de elementele HTML standard care alcătuiesc scheletul paginii, avem o foaie de stil personalizată, pe care o vom adăuga în doar un moment, și o foaie de stil oferită de jQuery UI. În partea de jos a paginii, chiar înainte de închidere tag-ul, avem o referință la jQuery (versiunea curentă la momentul scrierii este 1.4.4), o referință la jQuery UI (versiunea curentă 1.8.7) și o etichetă de script gol în care vom pune codul oferă editorului funcționalitatea sa.

Componentele jQuery UI pe care le vom folosi în acest exemplu sunt redimensionabile și dialog și tema este ui-lightness.

Elementele vizibile de pe pagină sunt destul de simple; avem un exterior care conține

element, în care se află două
elemente. Primul conține element pe care îl vom folosi pentru a manipula imaginea noastră. Al doilea conține o bară de instrumente cu butoane care va fi utilizată pentru a face manipulările. De la id atributelor acordate fiecărui buton ar trebui să fie destul de evident ce face fiecare buton.


Adăugarea stilurilor

Ca și HTML, CSS folosit este extrem de simplu și constă din următoarele:

#imageEditor width: 482px; margin: auto; padding: 20px; frontieră: 1px solid # 4b4b4b; -moz-border-radius: 8px; -webkit-border-radius: 8px; border-radius: 8px; culoare de fundal: #ababab;  #editorContainer display: block; lățime: 480 x; Înălțime: 480 x;  #editor display: block; margine: 0 20px 20px 0; frontieră: 1px solid # 4b4b4b;  #toolbar display: block; margine: 20px 0 0;  #toolbar o marginea-dreapta: 10px; schiță: nici una; Culoare: # 4b4b4b;  #resizer border: 2px dashed # 000;  #tip padding: 5px; margin: 0; frontieră: 1px solid # 000; -moz-border-radius: 3px; -webkit-border-radius: 3px; border-radius: 3px; Poziția: absolută; culoare de fundal: #fff; background-color: RGBA (255,255,255, .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); box-shadow: 1px 1px 1px rgba (0,0,0,0,5); 

Salvați ca image-editor.css în același director ca și pagina HTML. Nimic nu este cu adevărat remarcabil aici, mai ales aspectul stilurilor editorului și a elementelor sale constitutive în maniera ilustrată în captura de ecran de mai jos:



Full Screencast



Partea distractivă

Tot ce trebuie să faceți este să adăugați codul care face ca editorul să funcționeze. Începeți prin adăugarea codului de mai jos la cel gol > element în partea de jos a paginii:

(funcția ($) // obține panza și contextul var editor = document.getElementById ("editor"), context = editor.getContext ("2d"", src:" img / graffiti.png ", sarcina: funcția () context.drawImage (aceasta, 0, 0);, // codul care urmează să urmeze aici?) (jQuery);

Mai întâi de toate, punem tot codul nostru într-o închidere și aliasing obiect jQuery ca $ caracter. Îmi dau seama că jQuery se aliază automat caracterului $ pentru noi, însă există situații în care acest lucru poate provoca conflicte cu alte coduri care pot fi utilizate atunci când codul nostru este implementat de alții.

Acesta este, de asemenea, modul recomandat de a crea plugin-uri, așa că pur și simplu face acest lucru de fiecare dată când jQuery este folosit face mult mai rapid și mai ușor să se întoarcă și să transforme codul într-un plugin, dacă este necesar. Pur și simplu mi se pare mai convenabil să scriu tot codul meu jQuery într-un astfel de închidere. Are și alte beneficii, cum ar fi eliminarea dependenței de variabilele globale - toate variabilele pe care le creăm vor fi ascunse în siguranță de alte coduri în afara închiderii în majoritatea situațiilor.

Pentru a lucra cu pânza trebuie să luăm o referință la contextul acesteia. Acesta este un obiect reprezentând suprafața pânzei pe care se află cel mai a metodelor de lucru cu panza. O serie de metode pot fi chemați direct pe obiectul panvas, dar cele mai multe sunt numite în obiectul context.

Obținerea contextului este un proces în două etape; mai întâi se face referire la elementul în sine folosind JavaScript standard document.getElementById () metodă, vom apela apoi getContext () pe panza (aceasta este o astfel de metodă care poate fi apelată direct pe elementul de panza și pentru un motiv bun!), specificând 2d ca context. În prezent, 2d este singurul context care există pe scară largă, deși în viitor am putea să așteptăm cu nerăbdare să lucrăm cu contexte 3d.

Atât obiectele de pânză cât și obiectele de context sunt stocate în variabilele de nivel superior (echivalentul variabilelor globale nu lucrăm la o închidere), astfel încât orice funcții pe care le definim să le poată folosi.

Urmând aceste două variabile, noi creăm un altul, numit imagine. Folosim jQuery aici pentru a crea rapid un nou element de imagine. Am setat src a unei imagini (este inclusă o mostră de imagine fără drepturi de autor cu descărcarea de cod), astfel încât să avem ceva de lucrat și să adăugăm onload manipulator de evenimente care vopsește pur și simplu imaginea pe pânza pe care o încărcă imaginea. Este important atunci când lucrați cu pânza pentru a vă asigura că toate imaginile folosite sunt încărcate complet înainte de a fi adăugate pe pânză.

Imaginea este pictată pe pânză folosind drawImage () metoda, care este chemat pe context obiect. Această metodă are trei argumente (opțional poate dura mai mult, așa cum vom vedea mai târziu în exemplu); aceste argumente sunt imaginea de utilizat (la care se face referire folosind acest cuvânt cheie), X poziția pe panza pentru a începe desenarea imaginii și y poziție pe panza pentru a începe desenarea imaginii. Imaginea eșantionului este dimensiunea exactă a pânzei în acest exemplu, iar simplitatea este complet pătrată.

Acum suntem gata să adăugăm un cod în acest stadiu. Există virgulă după imaginea pe care am creat-o, deci următorul bit de cod pe care îl adăugăm va fi, de asemenea, o variabilă.


Adăugarea funcționalității barei de instrumente

Apoi trebuie să adăugăm codul pentru a gestiona butoanele barei de instrumente. Am putea adăuga o serie de agenți de procesare a clicurilor, unul pentru fiecare buton pe care dorim să-l adăugăm. Deși ușor de făcut, nu ar fi extrem de eficient și nu ar fi scalar incredibil de bine.

În mod ideal, dorim o singură funcție principală care să dea un clic pe orice buton și să invocă funcția corectă. Din fericire, acest lucru este, de asemenea, foarte ușor. Adăugați următorul cod direct după imaginea pe care tocmai l-am creat:

// toolbar funcții instrumente = ; $ ("# toolbar") copii () faceți clic pe (funcția (e) e.preventDefault ();

Este la fel de simplu ca asta. Să acoperim ceea ce face acest cod. Ultima variabilă de nivel superior pe care o creăm se numește unelte și conține un obiect gol (în acest stadiu). Funcțiile pentru fiecare buton individual vor fi puse în acest obiect, așa cum vom vedea în scurt timp.

Apoi adaugam un single clic handler, atașat la toți copiii elementului cu id-ul Bara de instrumente (unul dintre

elemente în HTML).

În cadrul acestei funcții de manipulare a clicurilor, oprim mai întâi comportamentul implicit al browserului, și anume urmărirea legăturii (acest lucru împiedică comportamentul nedorit al "jump-to-top" afișat uneori când utilizați standard elemente ca butoane).

În sfârșit, aplicăm JavaScript apel() metode pentru funcția conținută în proprietatea unelte obiect care se potrivește cu id atributul linkului la care a fost făcut clic. Deoarece tot ceea ce avem nevoie de link-ul pe care a fost dat click este acesta id atributul, putem folosi standardul acest cuvinte cheie fără a le împacheta într-un obiect jQuery. apel() metoda necesită ca acest cuvântul cheie este, de asemenea, transmis acestuia ca argument.

Acum, dacă adăugăm o funcție la obiectul de instrumente de sub proprietate Salvați, ori de câte ori faceți clic pe butonul din bara de instrumente cu id salvați, funcția va fi apelată. Deci, tot ce trebuie să facem acum este să adăugăm o funcție pentru fiecare dintre butoanele barei de instrumente.


Salvarea imaginii editate

Vom începe cu funcția de salvare deoarece este destul de mică și ușoară. Adăugați următorul cod la unelte obiect:

// output to  salvați: funcția () var saveDialog = $ ("
") .appendTo (" corp "); $ ("", src: editor.toDataURL ()) appendTo (saveDialog); saveDialog.dialog (resizable: false, modal: true, title:" lățime + 35);,

Primul lucru pe care funcția noastră îl face este să creeze un nou

și adăugați-l la a paginii. Acest element va fi utilizat împreună cu componenta de dialog a jQuery UI pentru a produce o casetă de dialog modală.

Apoi vom crea un nou element de imagine; de data aceasta am setat-o src la o reprezentare codată de bază 64 a tot ceea ce se află în interiorul pânzei. Această acțiune se efectuează utilizând toDataURL () , care, întâmplător, este o altă metodă chemată direct pe elementul de pânză. Odată creat, imaginea este atașată la

element creat în pasul anterior.

În final, inițializăm componenta de dialog; acest lucru sa făcut folosind dialog () , o metodă adăugată de jQuery UI. Un obiect literal este trecut la dialog () care ne permite să setăm diferite opțiuni de configurare. În acest caz, configurați dialogul astfel încât acesta să nu poată fi redimensionat și astfel încât să fie modal (o suprapunere va fi aplicată restului paginii în timp ce dialogul este deschis). De asemenea, setăm titlul dialogului la un șir care oferă instrucțiuni despre ce trebuie făcut pentru salvarea obiectului și face dialogul suficient de mare pentru a conține imaginea stabilindu-i lățimea până la lățimea elementului de pânză plus 35 pixeli.


Rotație

O caracteristică comună a editorilor de imagini este abilitatea de a roti un element și de a folosi funcționalitatea canvas încorporată, este destul de ușor să o implementăm în editorul nostru. Adăugați următoarele funcții după funcția de salvare:

rotați: funcția (conf) // salvați imaginea curentă înainte de a roti $ ("", src: editor.toDataURL (), load: function () // rotire canvas context.clearRect (0, 0, editor.width, editor.height); context.translate (conf.x, conf.y) ; context.rotate (conf.r); // redraw imaginea salvată context.drawImage (aceasta, 0, 0);); rotateL: function () var conf = x: 0; înălțime, r: -90 * Math.PI / 180; tools.rotate (conf); rotateR: function () var conf = x: editor.width, y: 0, r: 90 * Math.PI / 180; tools.rotate (conf);,

Așa că am adăugat trei noi funcții; o funcție master rotate și apoi o funcție pentru fiecare rotire stânga și rotiți butoanele barei de instrumente din dreapta. rotateL () și rotateR () funcțiile fiecare construi doar un obiect de configurare personalizat și apoi apelează comandantul roti() funcție, trecând în obiectul de configurare. Este stăpânul roti() care efectuează de fapt rotația. Un aspect important este acela că roata nu este imaginea de pe pânză.

Obiectul de configurare pe care îl creăm în rotateL () și rotateR () funcțiile sunt foarte simple; conține trei proprietăți - X, y și r. Proprietatile X și y se referă la cantitatea de traducere necesară și r este cantitatea de rotație. Fiecare clic pe un buton de rotire va roti imaginea cu plus sau minus 90 de grade.

În rotateL () trebuie să traducem panza la aceeași distanță ca înălțimea panzei pe axa verticală pentru a ne asigura că imaginea rămâne vizibilă odată ce panza a fost rotită. Rotația la "stânga" este clasificată ca rotație negativă, deoarece este în sens invers acelor de ceasornic. La calcularea unghiului de rotație nu putem folosi grade, avem nevoie să convertim 90 de grade (sau -90 grade în acest caz) în radiani. Acest lucru este ușor și necesită următoarea formulă:

Numărul de grade înmulțit cu Pi împărțit la 180

rotateR () funcția este la fel de dreaptă, de această dată traducem pânza pe axa orizontală în loc de axa verticală și folosim un număr pozitiv pentru rotire în sensul acelor de ceasornic.

În comandant roti() din nou, trebuie să luăm o copie a imaginii curente pe pânză, pe care o facem prin crearea unui nou element de imagine cu jQuery și stabilirea src la rezultatul toDataURL () din nou. De data aceasta vrem să desenați imaginea înapoi la panza odată ce pânza a fost rotită, astfel încât să adăugăm o imagine onload manipulator de evenimente pentru imagine.

Odată ce imaginea a fost încărcată, mai întâi ștergem pânza folosind clearRect () metodă. Această metodă are patru argumente; primele două argumente sunt X și y coordonează începerea compensării. Al treilea și al patrulea sunt dimensiunile zonei care trebuie curățate. Vrem să ștergem întreaga pânză astfel încât să începem la 0,0 (colțul din stânga sus al pânzei) și să ștergem toată lățimea și înălțimea pânzei.

Odată ce am eliminat pânza pe care o traducem (o mutați în esență) folosind Traduceți() metoda de transformare. Vom traduce fie înălțimea completă, fie întreaga lățime a pânzei, în funcție de dacă rotateL () sau rotateR () funcția a inițiat rotația. Traducerea pânzei este necesară deoarece, în mod implicit, rotația are loc în jurul dreptului de jos al pânzei, nu în mijloc așa cum v-ați aștepta.

Apoi, putem roti pânza și apoi retușați imaginea înapoi la pânză. Chiar dacă desenăm aceeași imagine înapoi pe pânză, panza a fost rotită, astfel încât imaginea să fie și ea rotită automat. Din nou, ne putem referi la imaginea care trecea la drawImage () metoda ca acest deoarece suntem în interiorul dispozitivului de preluare a sarcinii pentru imagine și jQuery asigură că acest lucru se referă la imagine. În următoarea captură de ecran se afișează imaginea rotită spre stânga:



Redimensionarea imaginii

Redimensionarea imaginii este interacțiunea noastră cea mai complexă, iar funcția necesară pentru ao face este destul de mare, chiar dacă redimensionarea pânzei în sine este destul de banală. Adăugați următoarea funcție la obiectul instrumente după funcțiile de rotație la care ne-am uitat:

redimensionare: functie () // crea resizable pe panza var coords = $ (editor) .offset (), resizer = $ ("
", id:" resizer "). css (poziție:" absolut ", stânga: coords.left, top: coords.top, width: editor.width - 1, height: editor.height - 1). appendTo ("corp"); 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, redimensionare: functie (e, ui) resizeWidth = Math.round (ui.size.width); resizeHeight = Math.round (ui.size.height); // tooltip pentru a arata o noua dimensiune var string = "Lățimea nouă:" + resizeWidth + "px,
noua limita: "+ resizeHeight +" px "; daca ($ (" tip "). : "tip", html: string) css (left: xpos, top: ypos) appendTo ("body"); acesta var confirmDialog = $ ("
", html:" Imaginea va fi redimensionată la "+ resizeWidth +" și la "+ resizeHeight +" înălțime mare.
Continuați? "); // confirmă dialogul de dialog confirmareDialog.dialog (resizable: false, modal: true, title:" Confirmare redimensionare? ", Butoane: Cancel: function () tidy up $ (this). ()), da: funcție () // ordonați $ (acest) .dialog ("închide"); resizer () .Remove (); $ ("# tip") remove (); $ ("", src: editor.toDataURL (), load: function () // elimina vechea imagine context.clearRect (0, 0, editor.width, editor.height); // redimensiona canvas editor.width = resizeWidth; editor .height = resizeHeight; // redraw imaginea salvată context.drawImage (aceasta, 0, 0, resizeWidth, resizeHeight););););,

Deci, să vedem pașii necesari funcției noastre de redimensionare. În primul rând, avem nevoie de o modalitate de a indica utilizatorului în ce mărime va fi redimensionată imaginea, iar utilizatorul necesită un mod de a seta noua dimensiune. Apoi, dorim să confirmăm dacă utilizatorul dorește să aplice noua dimensiune și, dacă este cazul, să aplice noua dimensiune. Noua funcție face toate lucrurile, să vedem cum.

Mai intai primim coordonatele pe pagina elementului canvas folosind jQuery offset () astfel încât să știm unde să poziționăm elementul redimensionabil. Apoi creăm un nou

element, care va deveni redimensionabil, și să-i dați un id de redimensiona astfel încât să putem să ne referim cu ușurință la acesta. De asemenea, stabilim unele proprietăți ale stilului noului element pentru a-l poziționa pe panza. Odată ce aceste stiluri sunt setate, noi le adăugăm la a paginii. Dimensiunea redimensionabilă va apărea ca o margine punctată în jurul interiorului panzei, după cum se arată mai jos:


Apoi vom inițializa încă două variabile, dar le vom stabili valorile nul pentru moment. Acestea vor fi folosite pentru a stoca lățimea și înălțimea pe care se poate schimba redimensionabil la redimensionare. Aceste variabile vor fi populate și utilizate mai târziu în funcție. xpos și ypos variabilele sunt folosite pentru a poziționa un sfat util pe care îl vom crea într-un moment. Ele poziționează vârful instrumentului la 5 pixeli de la marginea din stânga și de la marginea superioară a pânzei.

Apoi inițializăm resizable folosind jQuery UI resizable () metodă. Configurați dimensiunea redimensionabilă pentru a avea raportul de aspect blocat; imaginea noastră este pătrată, așa că dorim ca ea să rămână pătată, indiferent de mărimea acesteia. De asemenea, asigurăm că imaginea nu poate fi mărită în așa fel încât să se păstreze calitatea imaginii. Dacă imaginea ar fi fost mărită în loc să fie mărită, ar deveni blocată. lățimea maximă și maxHeight opțiunile de configurare asigură faptul că imaginea poate fi micșorată. Ambele sunt setate la lățimea și înălțimea curentă a panzei, respectiv.

Componenta redimensionabilă are unele handlers de evenimente personalizate pe care le putem atribui funcții care vor fi executate atunci când aceste evenimente personalizate sunt declanșate. Utilizăm două dintre acești agenți de procesare a evenimentelor pentru acest exemplu; redimensiona, care va fi concediat de fiecare dată când dimensiunea redimensionabilă este redimensionată și Stop care este declanșată odată ce dimensiunea redimensionabilă a fost redimensionată.

Funcția de redimensionare poate primi două argumente; primul este un obiect de eveniment, pe care nu trebuie să îl folosim în acest exemplu, dar care trebuie declarat pentru a putea folosi al doilea argument, de care avem nevoie. Al doilea argument este un obiect care conține informații utile despre dimensiunea redusă, inclusiv mărimea la care a fost modificată. Primul lucru pe care îl facem în această funcție este să alocăm noua dimensiune a dimensiunilor reduse resizeWidth și resizeHeight variabilele care utilizează proprietățile ui obiecte pe care le primește funcția.

Ultimul lucru pe care această funcție îl face este să creeze sfatul de instrucțiuni care îi spune utilizatorului cât de mare este în prezent redimensionabil. Dacă există deja această indicație, nu este nevoie să o recreăm și să putem seta textul interior într-un șir care să indice mărimea curentă a dimensiunilor reduse. Dacă simbolul degetului nu există deja, cum ar fi prima dată când dimensiunea redimensionabilă este redimensionată, o creăm de la zero. Bara de instrumente este poziționată utilizând xpos și ypos pe care am creat-o mai devreme. Șirul este construit de la zero la fiecare schimbare a dimensiunilor redimensionabile. Bara de instrumente va apărea astfel:


Funcția stop, care se execută o dată când se termină interacțiunea de redimensionare, creează mai întâi un nou element de dialog care verifică dacă vizitatorul dorește să aplice noua dimensiune panzei. Din nou, dialogul este configurat astfel încât să nu poată fi redus în sine și astfel încât să fie modal. De asemenea, adăugăm câteva butoane în acest dialog. Primul este a Anulare care permite vizitatorului să renunțe la operația de redimensionare fără a aplica noua dimensiune. Tot ce facem aici este o menajare, eliminând dialogul, dimensiunea redusă și bara de instrumente.

De asemenea, creăm un da butonul care aplică noua dimensiune. De asemenea, facem aceleași sarcini de întreținere aici, dar apoi, pentru a aplica noua dimensiune, creăm o nouă imagine încă o dată, în același mod pe care l-am făcut deja de mai multe ori. Stabilirea unei noi dimensiuni a pânzei este extrem de ușoară; noi furnizam doar valorile la care a fost schimbat capacul la lățimea și înălțimea elementului de panza. Aici este dialogul, care apare la fel ca dialogul de salvare de mai devreme, cu conținut diferit:



Schimbarea valorilor rgb ale pixelilor individuali

Am spus mai devreme că avem un control complet la nivelul pixelilor asupra conținutului elementului de panza, astfel încât ultimele două funcții ale butonului din bara de instrumente vor face exact acest lucru. Prima funcție este utilizată pentru a converti imaginea în tonuri de gri, cea de-a doua schimbă imaginea în ton de sepia. Ne vom uita mai întâi la funcția de tonuri de gri:

tonuri de gri: functie () // obtine date de imagine var imgData = context.getImageData (0, 0, editor.width, editor.height), pxData = imgData.data, lungime = pxData.length; pentru (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); ,

Primul lucru pe care trebuie să-l facă această funcție este să obțină datele pixelului actual al pânzei. Noi folosim getImageData () metodă de a face acest lucru. Această metodă acceptă patru argumente, care sunt aceleași ca și clearRect () metoda pe care am privit mai devreme - primele două argumente sunt X și y pozițiile pentru a începe colectarea de date de la și a treia și a patra sunt lățimea și înălțimea zonei pentru a obține. Vrem întreaga pânză, astfel încât să începem la 0,0 (sus-stânga) și să continuăm pentru lățimea și înălțimea pânzei. Obiectul rezultat returnat prin metoda este stocat în imgData variabil.

Obiectul stocat în această variabilă are o proprietate numită date; în această proprietate este o matrice care conține r g b și valorile alfa pentru fiecare pixel din panza, astfel încât primul element din matrice să conțină r valoarea primului pixel, al doilea element conține g valoarea primului pixel, al treilea conține b valoarea primului pixel și cel de-al patrulea element conține valoarea alfa a primului pixel. Această matrice este incredibil de mare; o imagine de 480 × 480 pixeli conține 230400 pixeli și avem patru elemente pentru fiecare pixel. Aceasta face ca matricea să aibă un total de 921600 de elemente în lungime! Această lungime este, de asemenea, stocată pentru utilizarea în pentru buclă pe care o definim în continuare.

Ciclul pentru este puțin diferit de obicei pentru bucle. Amintiți-vă că matricea poate fi organizată în blocuri discrete de 4 elemente, în care fiecare element dintr-un singur bloc se referă la componentele individuale rgba, astfel încât să conectăm patru elemente simultan prin matrice. La fiecare iterație obținem fiecare componentă pixel și apoi folosim formula r * .3 + g * .59 + b * .11 pentru a converti fiecare în gri. Apoi salvăm componenta pixel convertită înapoi la elementul original al matricei.

Odată ce am făcut buclă peste întreaga matrice, putem scrie conținutul matricei înapoi la panza, înlocuind fiecare pixel original cu noua sa corespondență în nuanțe de gri folosind putImageData () metoda, care pur și simplu face opusul getImageData ().

Funcția ton sepia este identică cu funcția de tonuri de gri, cu excepția faptului că folosim o formulă diferită pentru a converti fiecare r g b componenta la ton sepia:

sepia: funcția () // obține datele de imagine var imgData = context.getImageData (0, 0, editor.width, editor.height), pxData = imgData.data, length = pxData.length; pentru (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); 

Iată o fotografie a imaginii odată ce a fost transformată în ton sepia:



Concluzie

În acest tutorial am văzut cum poate fi transformată panza într-un editor de imagini puternic care ne oferă o parte din funcționalitatea editorilor de imagine de bază, bazați pe aplicații, cu care suntem familiarizați. Acest exemplu ar putea fi extins cu ușurință pentru a adăuga alte caracteristici, precum trunchierea și desenarea cu un instrument creion, deși voi lăsa adăugarea acestei funcționalități pentru dvs. Vă mulțumim pentru lectură.