2013-08-31 15 views
11

ich ein kleines Bild, die ich auf einer Leinwand bin Rendering, wie folgt aus:Ändern der Größe einer Leinwand Bild ohne Unschärfen es

ctx.drawImage(img, 0, 0, img.width*2, img.height*2); 

Ich würde dies wie ein scharfes upsized Bild (4 identische Pixel für jeden zu zeigen, Bildpixel). Dieser Code (in Chrome 29 auf dem Mac) macht jedoch ein verschwommenes Bild. In Photoshop sieht es so aus, als würde es "Bicubic" Resampling anstelle von "Nearest Neighbor" verwenden.

In einer Situation, wo es nützlich wäre (z. B. ein Retro-Spiel), Ist es möglich, ein scharfes vergrößertes Bild zu erzeugen, oder muss ich eine separate Bilddatei für jede Größe des Bildes auf dem Server haben?

+0

besten Weg, dies zu tun sind, getrennte Bilder für jede Größe haben (schnellste, gute Qualität), eine andere Möglichkeit ist, die größte Größe zu haben, um sie unterwegs zu verkleinern (minimaler Speicher, gute Qualität). – slash197

+0

@ slash197 Wenn ich herunterskaliere, hat es die gleiche Unschärfe. – JJJollyjim

+1

sollte es nicht verschwommen sein, behalten Sie das Seitenverhältnis? – slash197

Antwort

18

Einfach drehen Leinwand Anti-Aliasing für Bilder aus - leider ist diese Eigenschaft noch so hier voran Verkäufer die Variationen sind:

context.webkitImageSmoothingEnabled = false; 
context.mozImageSmoothingEnabled = false; 
context.imageSmoothingEnabled = false; /// future 

dann das Bild zeichnen.

Optional für ältere Versionen und Browser, die dies noch nicht implementiert hat, können Sie CSS anstelle:

canvas { 
    image-rendering: optimizeSpeed;    // Older versions of FF 
    image-rendering: -moz-crisp-edges;   // FF 6.0+ 
    image-rendering: -webkit-optimize-contrast; // Webkit (non standard naming) 
    image-rendering: -o-crisp-edges;   // OS X & Windows Opera (12.02+) 
    image-rendering: crisp-edges;    // Possible future browsers. 
    -ms-interpolation-mode: nearest-neighbor; // IE (non standard naming) 
} 

ONLINE TEST HERE

+1

Fantastisch, eine viel bessere (und elegantere) Lösung als das Herunterskalieren großer Dateien oder 'getImageData'. – JJJollyjim

+2

Das nicht vorfixierte 'context.imageSmoothingEnabled' funktioniert in Chrome mindestens ab Version 33. – Luke

1

prüfen diese Geige: http://jsfiddle.net/yPFjg/

Es lädt das Bild in eine Leinwand, erstellt dann eine verkleinerte Kopie und verwendet diese als Sprite.

Mit wenigen Änderungen können Sie einen Bildlader implementieren, der die Größe von Bildern während des Betriebs ändert.

var ctx = document.getElementById('canvas1').getContext('2d'); 
var img = new Image(); 
var original = document.createElement("canvas"); 
var scaled = document.createElement("canvas"); 

img.onload = function() { 
    var oc = original.getContext('2d'); 
    var sc = scaled.getContext('2d'); 
    oc.canvas.width = oc.canvas.height = 16; 
    sc.canvas.width = sc.canvas.height = 32; 
    oc.drawImage(this, 0, 0);  
    var od = oc.getImageData(0,0,16,16); 
    var sd = sc.getImageData(0,0,32,32); 
    for (var x=0; x<32; x++) { 
     for (var y=0; y<32; y++) { 
      for (var c=0; c<4; c++) {   
       // you can improve these calculations, I let them so for clarity   
       sd.data[(y*32+x)*4+c] = od.data[((y>>1)*16+(x>>1))*4+c]; 
      } 
     } 
    } 
    sc.putImageData(sd, 0, 0); 
    ctx.drawImage(scaled, 0, 0);  
} 

img.src = document.getElementById('sprite').src; 

Einige Anmerkungen zu getImageData: es gibt ein Objekt mit einem Array. Das Array hat eine Höhe * Breite * 4 Größe. Die Farbkomponenten werden in RGBA-Reihenfolge gespeichert (Rot, Grün, Blau, Alpha, jeweils 8 Bit).

+0

Dies funktioniert nicht für mich in Firefox (keine Fehler in der JS-Konsole). http://i.imgur.com/DDqlxTS.png – JJJollyjim

+0

für FF behoben. Ich habe die Bilderstellung geändert (Zeile 2) –

Verwandte Themen