Costruisci un editor di immagini su tela con tela

Non abbiamo intenzione di scatenarci, non c'è tempo, ma vedremo quanto è facile fare cose come rotazione, ridimensionamento, traduzione e persino manipolazione del colore sottile. Non illudetevi di finire con Photoshop, anche se questo è teoricamente possibile, ma considerando che stiamo lavorando all'interno di nulla di più complesso di un browser, personalmente penso ancora che sia piuttosto notevole.

Questo tutorial include uno screencast disponibile per i membri Tuts + Premium.


Di cosa avrai bisogno per questo tutorial

Per produrre localmente una versione funzionante della demo dovrai utilizzare un browser basato su Webkit come Safari o Chrome o Opera. La demo funzionerà su Firefox, ma dovrà funzionare attraverso un web server per far funzionare la maggior parte delle funzionalità. Non pensare nemmeno all'utilizzo di IE; solo la versione 9 approva il supporto per l'elemento canvas e, sinceramente, non mi fido nemmeno di IE9 per rendere correttamente il codice e la funzionalità.


Iniziare

L'HTML sottostante è davvero piuttosto banale; tutto ciò di cui abbiamo bisogno per la struttura dell'editor sono i seguenti elementi di base:

    Canvas Image Editor     
Salva Ruota a sinistra Ruota a destra Ridimensiona seppia in bianco e nero

Salva la pagina come image-editor.html. A parte gli elementi HTML standard che compongono lo scheletro della pagina, abbiamo un foglio di stile personalizzato, che aggiungeremo in un momento, e un foglio di stile fornito dall'interfaccia utente di jQuery. In fondo alla pagina, poco prima della chiusura tag, abbiamo un riferimento a jQuery (la versione corrente al momento della scrittura è 1.4.4), un riferimento all'interfaccia utente jQuery (versione corrente 1.8.7) e un tag script vuoto in cui metteremo il codice che dà all'editor la sua funzionalità.

I componenti dell'interfaccia utente jQuery che utilizzeremo in questo esempio sono ridimensionabili e di dialogo, e il tema è l'ui-lightness.

Gli elementi visibili nella pagina sono piuttosto elementari; abbiamo un esterno contenente

elemento, all'interno del quale risiedono due
elementi. Il primo contiene il elemento che useremo per manipolare la nostra immagine. Il secondo contiene una barra degli strumenti che verrà utilizzata per eseguire le manipolazioni. Dal id attributi dati ad ogni pulsante dovrebbe essere abbastanza ovvio su cosa fa ogni pulsante.


Aggiungere gli stili

Come l'HTML, il CSS utilizzato è estremamente semplice e consiste nel seguente:

#imageEditor width: 482px; margin: auto; padding: 20px; border: 1px solid # 4b4b4b; -moz-border-radius: 8px; -webkit-border-radius: 8px; border-radius: 8px; background-color: #ababab;  #editorContainer display: block; larghezza: 480px; altezza: 480px;  #editor display: block; margine: 0 20px 20px 0; border: 1px solid # 4b4b4b;  #toolbar display: block; margine: 20px 0 0;  #toolbar a margin-right: 10px; delineare: none; color: # 4b4b4b;  #resizer border: 2px dashed # 000;  #tip padding: 5px; margin: 0; border: 1px solid # 000; -moz-border-radius: 3px; -webkit-border-radius: 3px; border-radius: 3px; position: absolute; background-color: #fff; background-color: 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); box-shadow: 1px 1px 1px rgba (0,0,0,0,5); 

Salva questo come image-editor.css nella stessa directory della pagina HTML. Non c'è nulla di veramente notevole qui, per lo più il layout degli stili dell'editor e dei suoi elementi costitutivi nel modo illustrato nello screenshot seguente:



Screencast completo



La parte divertente

Tutto quello che resta da fare è aggiungere il codice che fa funzionare l'editor. Inizia aggiungendo il codice sottostante al vuoto > elemento in fondo alla pagina:

(function ($) // get canvas e context var editor = document.getElementById ("editor"), context = editor.getContext ("2d"), // create / load image image = $ ("", src:" img / graffiti.png ", carica: function () context.drawImage (this, 0, 0);), // altro codice da seguire qui?) (jQuery);

Prima di tutto, stiamo mettendo tutto il nostro codice in una chiusura e aliasing dell'oggetto jQuery come $ personaggio. Mi rendo conto che jQuery si autoalimenta automaticamente con il carattere $ per noi, tuttavia, ci sono situazioni in cui questo può causare conflitti con altri codici che potrebbero essere in uso quando il nostro codice viene implementato da altri.

Questo è anche il modo consigliato di creare plugin, quindi è sufficiente farlo ogni volta che jQuery viene utilizzato, rendendo molto più rapido e semplice tornare indietro e trasformare il codice in un plugin, se necessario. Semplicemente trovo più comodo scrivere tutto il mio codice jQuery all'interno di una chiusura come questa. Ha anche altri vantaggi, come la rimozione di una dipendenza dalle variabili globali: tutte le variabili che creiamo saranno nascoste in modo sicuro da altri codici al di fuori della chiusura nella maggior parte delle situazioni.

Per lavorare con la tela dobbiamo ottenere un riferimento al suo contesto. Questo è un oggetto che rappresenta la superficie della tela su cui maggior parte dei metodi per lavorare con la tela vengono chiamati. Un paio di metodi possono essere richiamati direttamente sull'oggetto canvas, ma la maggior parte viene richiamata sull'oggetto contesto.

Ottenere il contesto è un processo in due fasi; per prima cosa abbiamo un riferimento al elemento stesso usando il codice JavaScript standard document.getElementById () metodo, quindi chiamiamo il getContext () metodo sulla tela (questo è uno di questi metodi che può essere chiamato direttamente sull'elemento canvas, e per una buona ragione!), specificando 2d come il contesto. Al momento attuale, 2d è l'unico contesto che esiste ampiamente, anche se in futuro potremmo essere in grado di guardare avanti per lavorare con i contesti 3D.

Sia la tela che gli oggetti di contesto sono memorizzati in variabili di primo livello (l'equivalente di variabili globali non si lavorava all'interno di una chiusura) in modo che tutte le funzioni che definiamo possano farne uso.

Seguendo queste due variabili ne creiamo un'altra, chiamata Immagine. Usiamo jQuery qui per creare rapidamente e senza sforzo un nuovo elemento immagine. Abbiamo impostato il src di un'immagine (un campione, l'immagine royalty-free è inclusa con il download del codice) in modo che abbiamo qualcosa con cui lavorare, e aggiungere un onload gestore di eventi che semplicemente dipinge l'immagine sulla tela che l'immagine ha caricato. È importante lavorare con la tela per garantire che tutte le immagini utilizzate siano caricate completamente prima di essere aggiunte al canvas.

L'immagine è dipinta sulla tela usando il drawImage () metodo, che viene chiamato sul contesto oggetto. Questo metodo prende tre argomenti (potrebbe facoltativamente richiedere più, come vedremo più avanti nell'esempio); questi argomenti sono l'immagine da usare (riferita all'uso di Questo parola chiave), il X posiziona sulla tela per iniziare a disegnare l'immagine, e il y posiziona sulla tela per iniziare a disegnare l'immagine. L'immagine di esempio è la dimensione esatta della tela in questo esempio e per semplicità è completamente quadrata.

Siamo ora pronti per aggiungere altro codice in questa fase. C'è una virgola finale dopo l'immagine che abbiamo creato, quindi il prossimo bit di codice che aggiungiamo sarà anche una variabile.


Aggiunta della funzionalità della barra degli strumenti

Quindi è necessario aggiungere il codice per gestire i pulsanti della barra degli strumenti. Potremmo semplicemente aggiungere una serie di gestori di clic, uno per ogni pulsante che desideriamo aggiungere. Sebbene sia facile da fare, non sarebbe enormemente efficiente e non sarebbe in grado di scalare incredibilmente bene.

Idealmente vogliamo una singola funzione master che gestisca un clic su qualsiasi pulsante e invochi la funzione corretta. Fortunatamente, questo è anche molto facile. Aggiungi il seguente codice direttamente dopo l'immagine che abbiamo appena creato:

// strumenti delle funzioni della barra degli strumenti = ; $ ("# toolbar"). children (). click (function (e) e.preventDefault (); // chiama gli strumenti di funzione rilevanti [this.id] .call (this););

E 'così semplice. Vediamo cosa fa questo codice. L'ultima variabile di livello superiore che creiamo si chiama tools e contiene un oggetto vuoto (in questa fase). Le funzioni per ogni singolo pulsante verranno inserite in questo oggetto, come vedremo tra poco.

Quindi aggiungiamo un singolo clic gestore, collegato a tutti i bambini dell'elemento con l'id barra degli strumenti (uno di

elementi nel codice HTML sottostante).

All'interno di questa funzione di gestione dei clic, prima interrompiamo il comportamento predefinito del browser, che sarebbe quello di seguire il collegamento (questo impedisce il comportamento indesiderato "jump-to-top" a volte esibito quando si utilizza lo standard elementi come pulsanti).

Infine applichiamo il JavaScript chiamata() metodo alla funzione contenuta nella proprietà di utensili oggetto che corrisponde al id attributo del collegamento su cui è stato fatto clic. Come tutto ciò di cui abbiamo bisogno dal link su cui è stato fatto clic è suo id attributo, possiamo usare lo standard Questo parola chiave senza avvolgerla in un oggetto jQuery. Il chiamata() metodo richiede che il Questo anche la parola chiave viene passata come argomento.

Ora, se aggiungiamo una funzione all'oggetto tools sotto la proprietà salvare, ogni volta che clicchiamo sul pulsante della barra degli strumenti con id salva, la funzione verrà chiamata. Quindi tutto ciò che dobbiamo fare ora è aggiungere una funzione per ciascuno dei nostri pulsanti della barra degli strumenti.


Salvataggio dell'immagine modificata

Inizieremo con la funzione di salvataggio poiché è piuttosto piccola e facile. Aggiungi il seguente codice al utensili oggetto:

// output a  save: function () var saveDialog = $ ("
") .appendTo (" body "); $ ("", src: editor.toDataURL ()). appendTo (saveDialog); saveDialog.dialog (ridimensionabile: false, modal: true, title:" Fai clic destro e scegli 'Salva immagine come' ", larghezza: editor. larghezza + 35);,

La prima cosa che fa la nostra funzione è creare un nuovo

elemento e aggiungilo al della pagina. Questo elemento verrà utilizzato insieme al componente di dialogo dell'interfaccia utente di jQuery per produrre una finestra di dialogo modale.

Successivamente creiamo un nuovo elemento immagine; questa volta abbiamo impostato è src a una rappresentazione codificata in base 64 di tutto ciò che è contenuto nella tela. Questa azione viene eseguita utilizzando il toDataURL () metodo, che per inciso, è un altro metodo chiamato direttamente sull'elemento canvas. Una volta creato, l'immagine viene aggiunta al

elemento creato nel passaggio precedente.

Infine, inizializziamo il componente di dialogo; questo fatto usando il dialogo() metodo, un metodo aggiunto dall'interfaccia utente di jQuery. Un oggetto letterale è passato al dialogo() metodo che ci consente di impostare le diverse opzioni di configurazione. In questa istanza configuriamo la finestra di dialogo in modo che non sia ridimensionabile e in modo che sia modale (una sovrapposizione verrà applicata al resto della pagina mentre la finestra di dialogo è aperta). Impostiamo anche il titolo della finestra di dialogo in una stringa dando istruzioni su cosa fare per salvare l'oggetto, e rendiamo il dialogo abbastanza grande da contenere l'immagine impostando la sua larghezza alla larghezza dell'elemento canvas più 35 pixel.


Rotazione

Una caratteristica comune degli editor di immagini è la possibilità di ruotare un elemento e, utilizzando la funzionalità di tela incorporata, è piuttosto semplice implementarlo nel nostro editor. Aggiungere le seguenti funzioni dopo la funzione di salvataggio:

ruotare: function (conf) // salva l'immagine corrente prima di ruotare $ ("", src: editor.toDataURL (), load: function () // ruota canvas context.clearRect (0, 0, editor.width, editor.height); context.translate (conf.x, conf.y) ; context.rotate (conf.r); // ridisegna l'immagine salvata context.drawImage (this, 0, 0););, rotateL: function () var conf = x: 0, y: editor. height, 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);,

Quindi abbiamo aggiunto tre nuove funzioni; una funzione di rotazione principale, quindi una funzione per ruotare a sinistra e ruotare i pulsanti di destra della barra degli strumenti. Il rotateL () e rotazione della () ogni funzione crea un oggetto di configurazione personalizzato e quindi chiama il master ruotare() funzione, passando l'oggetto di configurazione. È il padrone ruotare() funzione che esegue effettivamente la rotazione. Un punto importante da notare è che è la tela stessa che stiamo ruotando, non l'immagine sulla tela.

L'oggetto di configurazione che creiamo nel rotateL () e rotazione della () le funzioni sono molto semplici; contiene tre proprietà - X, y e r. Le proprietà X e y fare riferimento alla quantità di traduzione richiesta e r è la quantità di rotazione. Ogni clic su un pulsante di rotazione ruoterà l'immagine di più o meno 90 gradi.

Nel rotateL () funzione abbiamo bisogno di tradurre la tela alla stessa distanza dell'altezza della tela sull'asse verticale per garantire che l'immagine rimanga visibile una volta che la tela è stata ruotata. La rotazione a sinistra è classificata come rotazione negativa in senso antiorario. Quando calcoliamo l'angolo di rotazione non possiamo usare gradi, dobbiamo convertire 90 gradi (o -90 gradi in questo caso) in radianti. Questo è facile e richiede la seguente formula:

Il numero di gradi moltiplicato per Pi diviso per 180

Il rotazione della () la funzione è altrettanto semplice, questa volta traduciamo la tela sull'asse orizzontale anziché sull'asse verticale e usiamo un numero positivo per la rotazione in senso orario.

Nel maestro ruotare() abbiamo di nuovo bisogno di prendere una copia dell'immagine corrente sulla tela, che facciamo creando un nuovo elemento immagine con jQuery e impostandone il suo src al risultato del toDataURL () metodo di nuovo. Questa volta vorremmo riportare l'immagine sulla tela una volta che la tela è stata ruotata, quindi aggiungiamo un onload gestore di eventi all'immagine.

Una volta che l'immagine è stata caricata, prima cancelliamo la tela usando il clearRect () metodo. Questo metodo richiede quattro argomenti; i primi due argomenti sono i X e y coordinate per iniziare la compensazione. Il thrid e il quarto sono le dimensioni dell'area da cancellare. Vogliamo cancellare l'intera tela in modo da iniziare da 0,0 (l'angolo in alto a sinistra della tela) e cancellare l'intera larghezza e altezza della tela.

Una volta che abbiamo cancellato la tela, la traduciamo (spostandola essenzialmente) usando il tradurre() metodo di trasformazione. Lo tradurremo a tutta altezza, a tutta larghezza della tela a seconda che sia rotateL () o rotazione della () la funzione ha avviato la rotazione. La traduzione della tela è necessaria perché la rotazione predefinita avviene attorno alla parte inferiore destra della tela, non nel mezzo come ci si aspetterebbe.

Possiamo quindi ruotare la tela e quindi ridisegnare l'immagine all'area di disegno. Anche se stiamo riportando la stessa immagine sulla tela, la tela è stata ruotata in modo che anche l'immagine venga automaticamente ruotata. Ancora una volta, possiamo fare riferimento all'immagine per passare al drawImage () metodo come Questo perché siamo all'interno del gestore di carico per l'immagine e jQuery garantisce che si riferisca all'immagine. La prossima schermata mostra l'immagine ruotata a sinistra una volta:



Ridimensionamento dell'immagine

Il ridimensionamento dell'immagine è la nostra interazione più complessa e la funzione richiesta per farlo è piuttosto grande, anche se il ridimensionamento della tela è piuttosto banale. Aggiungi la seguente funzione all'oggetto tools dopo le funzioni di rotazione che abbiamo appena visto:

ridimensiona: function () // crea ridimensionabile su canvas var coords = $ (editor) .offset (), resizer = $ ("
", id:" resizer "). css (position:" absolute ", left: coords.left, top: coords.top, width: editor.width - 1, height: 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, ridimensiona: function (e, ui) resizeWidth = Math.round (ui.size.width); resizeHeight = Math.round (ui.size.height); // tooltip per mostrare le nuove dimensioni var string = "Nuova larghezza:" + ridimensiona + "px,
nuova altezza: "+ resizeHeight +" px "; if ($ (" # tip "). length) $ (" # tip "). html (stringa); else var tip = $ (" ", id : "tip", html: string). css (left: xpos, top: ypos). appendTo ("body");, stop: function (e, ui) // conferma ridimensiona, quindi esegui it var confirmDialog = $ ("
", html:" L'immagine verrà ridimensionata a "+ ridimensiona +" px di larghezza e "+ ridimensiona Altezza" px alta.
Procedere? "); // init conferma dialog confirmDialog.dialog (ridimensionabile: false, modal: true, titolo:" Conferma ridimensionamento? ", Pulsanti: Annulla: function () // riordina $ (this). dialog ("close"); resizer.remove (); $ ("# tip"). remove ();, Yes: function () // riordinare $ (this) .dialog ("close"); resizer .remove (); $ ("# tip"). remove (); $ ("", src: editor.toDataURL (), load: function () // rimuove la vecchia immagine context.clearRect (0, 0, editor.width, editor.height); // ridimensiona canvas editor.width = resizeWidth; editor .height = resizeHeight; // ridisegna l'immagine salvata context.drawImage (questo, 0, 0, resizeWidth, resizeHeight););;);,

Quindi vediamo i passaggi richiesti dalla nostra funzione di ridimensionamento. Per prima cosa abbiamo bisogno di un modo per indicare all'utente a quale dimensione verrà ridimensionata l'immagine, e l'utente ha bisogno di un modo per impostare la nuova dimensione. Vogliamo quindi confermare se l'utente desidera applicare la nuova dimensione e, in tal caso, applicare la nuova dimensione. La nuova funzione fa tutte le cose, vediamo come.

Per prima cosa otteniamo le coordinate sulla pagina dell'elemento canvas usando jQuery compensare() metodo, in modo da sapere dove posizionare l'elemento ridimensionabile. Quindi creiamo un nuovo

elemento, che diventerà ridimensionabile e fornirgli un id ridimensionare in modo che possiamo facilmente fare riferimento ad esso. Impostiamo anche alcune proprietà di stile del nuovo elemento per posizionarlo sulla tela. Una volta impostati questi stili, lo aggiungiamo al file della pagina. Il ridimensionabile verrà visualizzato come un bordo tratteggiato all'interno della tela, come mostrato di seguito:


Quindi inizializziamo altre due variabili, ma impostiamo i loro valori su nullo per ora. Questi verranno utilizzati per memorizzare la larghezza e l'altezza a cui è ridimensionabile il ridimensionamento quando viene ridimensionato. Queste variabili verranno popolate e utilizzate successivamente nella funzione. Il xpos e ypos le variabili vengono utilizzate per posizionare un suggerimento che creeremo in un momento. Posizionano il tooltip a 5 pixel dal bordo sinistro e dal bordo superiore dell'area di disegno.

Successivamente inizializziamo il ridimensionabile usando l'interfaccia utente di jQuery ridimensionabile () metodo. Configuriamo il ridimensionabile per avere le proporzioni bloccate; la nostra immagine è quadrata, quindi vogliamo che rimanga quadrata qualunque sia la dimensione a cui è ridimensionata. Garantiamo inoltre che l'immagine non possa essere ingrandita per mantenere la qualità dell'immagine. Se l'immagine fosse ingrandita invece di essere ridotta, diventerebbe un blocco. Il larghezza massima e altezza massima le opzioni di configurazione assicurano che l'immagine possa essere ridotta solo Entrambi sono impostati rispettivamente sulla larghezza e altezza della tela corrente.

Il componente ridimensionabile ha alcuni gestori di eventi personalizzati che possiamo assegnare funzioni alle quali verranno eseguiti quando vengono attivati ​​questi eventi personalizzati. Usiamo due di questi gestori di eventi per questo esempio; ridimensionare, che verrà attivato ogni volta che ridimensionabile viene ridimensionato e Stop che viene attivato una volta ridimensionato il ridimensionamento.

La funzione di ridimensionamento può ricevere due argomenti; il primo è un oggetto evento, che non è necessario utilizzare in questo esempio, ma che deve essere dichiarato per utilizzare il secondo argomento, di cui abbiamo bisogno. Il secondo argomento è un oggetto che contiene informazioni utili sul ridimensionabile, inclusa la dimensione in cui è stato modificato. La prima cosa che facciamo in questa funzione è assegnare la nuova dimensione del ridimensionabile al nostro resizeWidth e resizeHeight variabili usando le proprietà del ui oggetto che riceve la funzione.

L'ultima cosa che fa questa funzione è creare il suggerimento che dice all'utente quanto è grande il ridimensionabile al momento. Se questo tooltip esiste già, non è necessario ricrearlo e possiamo semplicemente impostare il suo testo interno su una stringa che mostri la dimensione corrente del ridimensionabile. Se il suggerimento non esiste già, come la prima volta che ridimensionabile viene ridimensionato, lo creiamo da zero. Il tooltip è posizionato usando il xpos e ypos che abbiamo creato in precedenza. La stringa viene creata da zero ogni volta che le dimensioni ridimensionabili cambiano. Il suggerimento apparirà in questo modo:


La funzione stop, che viene eseguita una volta al termine dell'interazione di ridimensionamento, crea innanzitutto un nuovo elemento di dialogo che controlla che il visitatore desideri applicare la nuova dimensione al canvas. Ancora una volta la finestra di dialogo è configurata in modo che non sia ridimensionabile e che sia modale. Aggiungiamo anche alcuni pulsanti a questa finestra di dialogo. Il primo è a Annulla pulsante, che consente al visitatore di uscire dall'operazione di ridimensionamento senza applicare la nuova dimensione. Tutto quello che facciamo qui è un po 'di pulizia, rimuovendo la finestra di dialogo, il ridimensionabile e il suggerimento.

Creiamo anche a pulsante che applica la nuova dimensione. Facciamo anche gli stessi compiti di pulizia qui, ma poi per applicare le nuove dimensioni creiamo una nuova immagine ancora una volta nello stesso modo in cui l'abbiamo già fatto diverse volte. Impostare la nuova dimensione della tela è estremamente semplice; forniamo solo i valori a cui è stato modificato il ridimensionabile alle proprietà width e height dell'elemento canvas. Ecco la finestra di dialogo, che appare uguale alla finestra di salvataggio precedente, solo con contenuti diversi:



Modifica dei valori rgb dei singoli pixel

Ho detto prima che abbiamo un controllo a livello di pixel completo del contenuto dell'elemento canvas, quindi le nostre ultime due funzioni dei pulsanti della barra degli strumenti faranno esattamente questo. La prima funzione viene utilizzata per convertire l'immagine in scala di grigi, la seconda modifica l'immagine in tonalità seppia. Osserveremo prima la funzione di scala di grigi:

greyscale: function () // recupera i dati dell'immagine var imgData = context.getImageData (0, 0, editor.width, editor.height), pxData = imgData.data, length = pxData.length; per (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 prima cosa che questa funzione deve fare è ottenere i dati pixel attuali della tela. Noi usiamo il getImageData () metodo per fare questo Questo metodo accetta quattro argomenti, che sono gli stessi di clearRect () metodo che abbiamo visto prima - i primi due argomenti sono i X e y posizioni per iniziare a raccogliere dati da e il terzo e il quarto sono la larghezza e l'altezza dell'area da ottenere. Vogliamo l'intera tela così partiamo da 0,0 (in alto a sinistra) e continuiamo per la larghezza e l'altezza della tela. L'oggetto risultante restituito dal metodo viene archiviato nel file imgData variabile.

L'oggetto memorizzato in questa variabile ha una proprietà chiamata dati; all'interno di questa proprietà è un array contenente il r g B e valori alfa per ogni singolo pixel nell'area di disegno, quindi il primo elemento nell'array conterrà il r valore del primo pixel, il secondo elemento contiene il g valore del primo pixel, il terzo contiene il B valore del primo pixel e il quarto elemento contiene il valore alfa del pixel del pugno. Questa matrice è incredibilmente grande; un'immagine di 480 x 480 pixel contiene 230400 pixel e abbiamo quattro elementi per ogni singolo pixel. Questo rende la matrice un totale di 921600 articoli in lunghezza! Questa lunghezza è anche memorizzata per l'uso in per ciclo che definiamo dopo.

Il ciclo for è un po 'diverso dal solito per i loop. Ricorda, l'array può essere organizzato in blocchi discreti di 4 elementi, in cui ogni elemento in un blocco singolo fa riferimento ai singoli componenti rgba, quindi eseguiamo un ciclo attraverso l'array di quattro elementi alla volta. In ogni iterazione otteniamo ogni componente pixel e quindi usiamo la formula r * .3 + g * .59 + b * .11 per convertire ciascuno in scala di grigi. Quindi salviamo il componente di pixel convertito nuovamente nell'elemento di matrice originale.

Una volta passato l'intero array, possiamo scrivere nuovamente il contenuto dell'array sulla tela, sostituendo ogni pixel originale con la sua nuova controparte in scala di grigi usando il putImageData () metodo, che fa semplicemente l'opposto di getImageData ().

La funzione di tonalità seppia è identica alla funzione di scala di grigi tranne per il fatto che utilizziamo una formula diversa per convertirli r g B componente al tono seppia:

sepia: function () // get image data var imgData = context.getImageData (0, 0, editor.width, editor.height), pxData = imgData.data, length = pxData.length; per (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); 

Ecco una ripresa dell'immagine una volta convertita in tonalità seppia:



Conclusione

In questo tutorial abbiamo visto come la tela può essere trasformata in un potente editor di immagini che ci offre alcune delle funzionalità degli editor di immagini base e basati su applicazioni con cui abbiamo familiarità. Questo esempio potrebbe essere facilmente esteso per aggiungere altre funzionalità, come il ritaglio e il disegno con uno strumento a matita, anche se lascerò l'aggiunta di questa funzionalità. Grazie per aver letto.