Sto lavorando con una tela di dimensioni relativamente grandi in cui vengono disegnate varie cose (complesse). Quindi voglio salvare lo stato della tela, quindi posso resettarlo velocemente allo stato in cui si trova ora in un secondo momento. Io uso getImageData per questo e memorizzo i dati in una variabile. Quindi disegno un po 'di più sulla tela e successivamente ripristinerò la tela dove era quando ho salvato il suo stato, usando putImageData.Perché il valore di ImageData è così lento?
Tuttavia, risulta che ImageData è molto lento. Infatti, è più lento del semplice ridisegnare l'intero Canvas da zero, il che implica diversi DrawImage che coprono la maggior parte della superficie e oltre 40.000 operazioni lineTo seguite da tratti e riempimenti.
Il nuovo disegno di una tela di circa 2000 x 5000 pixel da zero richiede ~ 170 ms, utilizzando putImageData richiede ben 240ms. Perché ImageData è così lento rispetto al ridisegnare la tela, sebbene il ridisegno della tela comporti il riempimento dell'intera tela con drawImage e quindi riempiendo circa il 50% della tela con poligoni usando lineTo, stroke e fill. Quindi, in sostanza, ogni singolo pixel viene toccato almeno una volta durante il ridisegno.
Perché drawImage sembra essere molto più veloce di mettere ImageData (dopo tutto, la parte drawImage di ridisegnare la tela richiede meno di 30 ms). Ho deciso di provare a salvare lo stato della tela non usando getImageData, ma invece di usare canvas.toDataURL e quindi creare un'immagine dall'URL dei dati che avrei incollato a drawImage per disegnarla sulla tela. Risulta che questa intera procedura è molto più veloce e richiede solo circa 35ms.
Quindi, perché ImageData è molto più lento delle alternative (utilizzando getDataURL o semplicemente ridisegnando)? Come potrei accelerare ulteriormente le cose? C'è e se, qual è in generale il modo migliore per memorizzare lo stato di una tela?
(Tutti i numeri sono misurati usando Firebug dall'interno di Firefox)
Sarebbe interessante se potessi pubblicare una dimostrazione del tuo problema online da qualche parte. In noVNC (http://github.com/kanaka/noVNC) uso putImageData per molti array di dati immagine di piccole e medie dimensioni e non vedo un problema di prestazioni con putImageData. Forse ti stai imbattendo in uno specifico caso di performance pessimistica che dovrebbe essere bacato. – kanaka
Puoi dare un'occhiata qui http://www.danielbaulig.de/A3O/ Non funzionerà al 100% se la console di firebug è attiva, quindi assicurati di accenderla. La versione ritirata è quella che usa putImageData. Puoi attivarlo facendo clic su qualsiasi "tessera". Aggiorna la tela del buffer usando putImageData e quindi "evidenzia" il riquadro selezionato. In a3o_oo.js ci sono alcune righe commentate, che possono essere usate per passare dall'uso di putImageData (corrente), usando getDataURL (le due righe che citano this.boardBuffer) e il semplice ridisegno (la linea drawBoard) del buffer del canvas. –
Ottima domanda e grandi soluzioni. Ma hai mai scoperto la vera ragione per cui mettere ImageData è così lento rispetto a drawImage? – cherouvim