2012-10-18 6 views
15

Ecco un'immagine .png (sulla destra) e l'elemento canvas su cui ho disegnato l'immagine (a sinistra). Riesci a notare la differenza di qualità? La tela rende l'immagine con una perdita di qualità notevole. Cosa possiamo fare?canvas drawImage quality

Ho osservato questo risultato su Chrome e IE9. Gli altri probabilmente faranno la stessa cosa. Come rendere l'immagine è abbastanza usuale: Nello script creo un nuovo Image() oggetto, dopo che è stato caricato chiamo
context.drawImage(myimage, x, y);

Right: What I want, Left: What I get

EDIT:

Questa è l'immagine iniziale ho osservato sulla tela:
In more detail: What I got first

Ed ecco che cosa è la canva s rende dopo che ho scritto:
context.drawImage(myimage,parseInt(x),parseInt(y));
In more detail: What I get with rounded coordinates

cosa posso dire, grande uomo risposta. Tiratore scelto al meglio. Il cappello è fuori per te.

EDIT2:

ho provato context.drawImage(myimage, parseInt(x) + 0.5, parseInt(y)+ 0.5);, ecco il risultato:

In more detail: Worst case

Penso che sia peggiore del primo. Ho osservato questo su Chrome, su IE9 è un po 'come cattivo.

+0

> Prende un inchino ... :) – Nippey

+0

+1 per includere gli screenshot e l'aggiornamento con i risultati! :) –

+0

+1 amo le domande colorate – rupps

risposta

10

Ho appena creato una sovrapposizione di entrambe le immagini in modo che si neutralizzino a vicenda. Non ha funzionato, ho avuto problemi con i bordi.

overlayed image

prega di verificare se le coordinate sono interi x, y. utilizzo in virgola mobile numero qui potrebbe sfocare l'immagine alcune implementazioni cercano come di renderla "tra i pixel"

context.drawImage(myimage, parseInt(x), parseInt(y)); 

Se questa non funziona neanche, utilizzare il cercare di valore intero + 0,5
So per implementazioni OpenGL, devi usare le coordinate con 0.5 per colpire il centro di un pixel.

context.drawImage(myimage, parseInt(x)+0.5, parseInt(y)+0.5); 


EDIT:

Partenza this page su HTML5Rocks!

+0

grazie, darò una prova e tornerò qui con i risultati – Halo

5

So che questo è già stato risposto, ma voglio dare maggiori informazioni per parlare di quello che sta succedendo qui e cosa si può fare.


Questo è causa di smoothing delle immagini, che per impostazione predefinita per lisciare algoritmi come bilineare/trilieaner/bicubico su tela per impostazione predefinita, mentre ciò che si vuole è conosciuto come primi vicini.

La specifica ha recentemente aggiunto una proprietà denominata imageSmoothingEnabled, che per impostazione predefinita è true e determina se le immagini disegnate su coordinate non interi o disegnate in scala utilizzeranno un algoritmo più fluido. Se è impostato su false, viene utilizzato il neighbor-neighbor più vicino, producendo un'immagine meno uniforme e creando solo pixel dall'aspetto più grande.

Il livellamento delle immagini è stato aggiunto solo di recente alle specifiche del canvas e non è supportato da tutti i browser, ma alcuni browser hanno implementato versioni con prefisso del produttore di questa proprietà. Nel contesto esiste mozImageSmoothingEnabled in Firefox e webkitImageSmoothingEnabled in Chrome e Safari, e impostandoli su false si fermerà l'anti-aliasing. Sfortunatamente, al momento della stesura di questo documento, IE9 e Opera non hanno implementato questa proprietà, il venditore ha prefisso o altro.

In generale è sufficiente seguire due regole:

  1. Se si sta ridimensionando la tela, è necessario disabilitare Immagini uniformi o ridimensionarlo utilizzando primi vicini di interpolazione. Ci sono alcuni algoritmi per farlo manualmente in questo momento e questo è ciò che stanno facendo le opzioni sopra.
  2. Se non si stanno disegnando coordinate intere, si otterrà lo stesso problema e si avrà la stessa soluzione. Se le opzioni di cui sopra non esistono sul tuo browser è necessario tornare a coordinate intere (x | 0, y | 0)

Dove x | 0 piani x rapidamente, tuttavia non funzionerà con i numeri più grandi di 2.147.483.647: Il più grande numero intero con segno a 32 bit.

Speriamo che le tue coordinate non siano più grandi di così!

-1

Penso che questo link sarà d'aiuto. Ho fatto lo stesso, ma nel mio caso conferisco il peso e l'altezza della tela in modo dinamico usando javascript. Poi ho dato l'altezza e la larghezza alla tela quando la dichiaro. Questo risolve il problema.