2014-11-06 8 views
12

Sto usando glfx.js per modificare la mia immagine ma quando sto cercando di ottenere i dati di quell'immagine usando la funzione toDataURL() ottengo un'immagine vuota (larghezza delle stesse dimensioni dell'originale Immagine).Canvas toDataURL() restituisce un'immagine vuota solo in Firefox

La cosa strana è che in Chrome la sceneggiatura funziona perfettamente.

Quello che voglio dire è che l'immagine viene caricata nel canvas utilizzando l'evento onload:

  img.onload = function(){ 

       try { 
        canvas = fx.canvas(); 
       } catch (e) { 
        alert(e); 
        return; 
       } 

       // convert the image to a texture 
       texture = canvas.texture(img); 

       // draw and update canvas 
       canvas.draw(texture).update(); 

       // replace the image with the canvas 
       img.parentNode.insertBefore(canvas, img); 
       img.parentNode.removeChild(img); 

      } 

anche il percorso della mia immagine è sullo stesso dominio;

Il problema (in Firefox) è quando premo il pulsante Salva. Chrome restituisce il risultato previsto ma Firefox restituisce questo:

data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAA7YAAAIWCAYAAABjkRHCAAAHxklEQVR4nO3BMQEAAADCoPVPbQZ/oAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 
... [ lots of A s ] ... 
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAzwD6aAABkwvPRgAAAABJRU5ErkJggg== 

Cosa potrebbe causare questo risultato e come posso risolvere il problema?

+0

L'immagine si sta modificando sullo stesso dominio? Giusto per escludere l'ovvio. – A1rPun

+0

Sì, lo è. Modificherò il mio post per menzionarlo! C'è un problema in Firefox (e non in Chrome) con immagini che non si trovano sullo stesso dominio? – boyd

+0

Sembra un'operazione asincrona che si svolge da qualche parte. Se l'immagine non viene caricata quando viene richiamato toDataURL(), il canvas sarà vuoto. – K3N

risposta

11

Molto probabilmente c'è un evento asincrono tra il momento in cui disegni sulla tela e l'ora in cui chiami toDataURL. Per impostazione predefinita, la tela viene cancellata dopo ogni composito. O impedire la tela di essere eliminato con la creazione di un contesto WebGL con preserveDrawingBuffer: true come in

var gl = canvas.getContext("webgl", {preserveDrawingBuffer: true}); 

o assicurarsi toDataURL è chiamato prima di uscire qualsiasi evento che si sta utilizzando per il rendering. Per esempio, se si esegue questa operazione

function render() { 
    drawScene(); 
    requestAnimationFrame(render); 
} 
render(); 

E da qualche altra parte fare questo

someElement.addEventListener('click', function() { 
    var data = someCanvas.toDataURL(); 
}, false); 

Quei 2 eventi, il animation frame, e il click non sono sincronizzati e la tela può essere eliminato tra li chiama. Nota: la tela non apparirà deselezionata poichè ha un doppio buffer, ma il buffer su DateURL e gli altri comandi che effettuano il controllo del buffer vengono cancellati.

La soluzione è o utilizzare preserveDrawingBuffer o effettuare la chiamata a toDataURL all'interno dello stesso evento del rendering. Per esempio

var captureFrame = false; 

function render() { 
    drawScene(); 

    if (captureFrame) { 
    captureFrame = false; 
    var data = someCanvas.toDataURL(); 
    ... 
    } 

    requestAnimationFrame(render); 
} 
render(); 

someElement.addEventListener('click', function() { 
    captureFrame = true; 
}, false); 

Qual è il punto di preserveDrawingBuffer: false che è il default? Può essere notevolmente più veloce, soprattutto sui dispositivi mobili, per non dover conservare il buffer di disegno. Un altro modo per vederlo è che il browser ha bisogno di 2 copie della tua tela. Quello a cui stai disegnando e quello che sta visualizzando. Ha 2 modi per gestire questi 2 buffer. (A) doppio tampone. Permetti di disegnare a uno, visualizzare l'altro, scambiare i buffer quando hai finito il rendering che è dedotto dall'uscita da qualsiasi evento che ha emesso i comandi di estrazione (B) Copia il contenuto del buffer che stai disegnando per fare il buffer che viene visualizzato . Lo scambio è molto più veloce della copia. Quindi lo swapping è l'impostazione predefinita. Dipende dal browser cosa succede realmente. L'unico requisito è che se preserveDrawingBuffer è false che il buffer di disegno venga cancellato dopo un composito (che è ancora un altro evento asincrono e quindi imprevedibile) se preserveDrawingBuffer è true allora deve essere copiato in modo che il contenuto del disegno sia conservato.

+0

Perché sto usando la libreria glfx.js non ho accesso diretto al canvas e metodi di rendering. Ho chiamato l'evento di funzione toDataURL con un timeout di 5 secondi e non ha funzionato. Non penso che sia qualcosa di asincrono qui ... Può essere qualcos'altro? – boyd

+0

Chiamare aDataURL con un timeout di 5 secondi È UN EVENTO ASYNC. Sei in JavaScript. Hai la fonte di glfx.js. Cambiarlo. – gman

+0

Sono riuscito a risolvere il problema aggiornando l'elemento canvas con una funzione glfx ('update()'). Eppure non so perché questo problema fosse solo in FF e non in Chrome. Grazie! – boyd

Problemi correlati