2012-10-18 6 views
15

Hier ist ein .png Bild (rechts) und das canvas Element auf dem ich das Bild gezeichnet habe (auf der linken Seite). Kannst du den Qualitätsunterschied bemerken? Canvas rendert das Bild mit merklichem Qualitätsverlust. Was können wir tun?canvas drawBildqualität

Ich beobachtete dieses Ergebnis auf Chrome und IE9. Andere werden wahrscheinlich dasselbe tun. Wie ich das Bild machen ist durchaus üblich: In dem Skript erstelle ich ein neues Image() Objekt, nachdem es nenne ich
context.drawImage(myimage, x, y);

Right: What I want, Left: What I get

EDIT geladen wird:

Dies ist das erste Bild Ich habe auf der Leinwand beobachtet:
In more detail: What I got first

Und hier ist, was die Canva s macht, nachdem ich schrieb:
context.drawImage(myimage,parseInt(x),parseInt(y));
In more detail: What I get with rounded coordinates

Was kann ich sagen, großen Antwort Mann. Sharpshooting von seiner besten Seite. Der Hut ist für dich.

EDIT2:

Ich versuchte context.drawImage(myimage, parseInt(x) + 0.5, parseInt(y)+ 0.5);, hier ist das Ergebnis:

In more detail: Worst case

Ich denke, es ist schlimmer als die erste. Ich habe das auf Chrome beobachtet, auf IE9 ist es etwas genauso schlimm wie schlecht.

+0

> Nimmt einen Bogen ... :) – Nippey

+0

+1 für die Aufnahme von Screenshots und die Aktualisierung mit Ergebnissen! :) –

+0

+1 ich liebe bunte Fragen – rupps

Antwort

10

Ich habe gerade eine Überlagerung der beiden Bilder erstellt, so dass sie sich gegenseitig neutralisieren. Es hat nicht funktioniert, ich hatte Schwierigkeiten mit Kanten.

overlayed image

Bitte überprüfen Sie, ob Ihre Koordinaten x, y ganze Zahlen sind. hier Gleitkommazahl verwenden, kann Ihr Image als einige Implementierungen verwischen versuchen, es zu machen „zwischen den Pixeln“

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

Wenn auch dies nicht funktioniert, versuchen Sie den ganzzahligen Wert + 0,5
Ich weiß, verwenden Bei OpenGL-Implementierungen müssen Sie Koordinaten mit 0,5 verwenden, um die Mitte eines Pixels zu treffen.

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


EDIT:

Check out this page auf HTML5Rocks!

+0

danke, ich gebe denen einen Versuch und bin wieder hier mit den Ergebnissen – Halo

5

Ich weiß, dass dies bereits beantwortet wurde, aber ich möchte weitere Informationen geben, um darüber zu sprechen, was hier vor sich geht und was getan werden kann.


Dies ist wegen der Bildglättung, die Standardwerte Algorithmen wie bilinear/trilieaner/bikubische auf Leinwand standardmäßig glatt, während das, was Sie wollen ist bekannt als nächsten Nachbarn.

Die Spezifikation hat kürzlich eine Eigenschaft namens imageSmoothingEnabled hinzugefügt, die standardmäßig true ist und bestimmt, ob Bilder, die auf nicht ganzzahligen Koordinaten gezeichnet oder gezeichnet werden, einen glatteren Algorithmus verwenden. Wenn es auf false eingestellt ist, wird nearest-neighbour verwendet, wodurch ein weniger glattes Bild erzeugt wird und stattdessen einfach größere Pixel erzeugt werden.

Die Bildglättung wurde erst kürzlich der Canvas-Spezifikation hinzugefügt und wird nicht von allen Browsern unterstützt, aber einige Browser haben Versionen dieser Eigenschaft mit Herstellervorgaben implementiert. Im Kontext gibt es mozImageSmoothingEnabled in Firefox und webkitImageSmoothingEnabled in Chrome und Safari, und wenn diese auf false gesetzt werden, wird das Auftreten von Anti-Aliasing verhindert. Leider haben IE9 und Opera zum Zeitpunkt des Verfassens dieses Merkmals weder den Verkäufer noch das Präfix implementiert.

In der Regel müssen Sie nur zwei Regeln beachten:

  1. Wenn Sie die Leinwand skalieren, müssen Sie die Bildglättung deaktivieren oder skalieren, indem Nächster-Nachbar-Interpolation. Es gibt ein paar Algorithmen, um dies jetzt manuell zu tun, und dies ist, was die obigen Optionen tun.
  2. Wenn Sie nicht auf ganzzahligen Koordinaten zeichnen, erhalten Sie das gleiche Problem und es hat die gleiche Lösung. Wenn die oben genannten Optionen, die Sie nicht auf Ihrem Browser existieren werden integer zurückkehren müssen koordiniert (x | 0, y | 0)

Wo x | 0 Etagen x schnell, werden jedoch nicht mit Zahlen größer als 2,147,483,647 arbeiten: Die größte 32-Bit-Ganzzahl mit Vorzeichen.

Hoffentlich sind Ihre Koordinaten nicht größer als das!

-1

Ich denke, das link wird Hilfe voll sein. Ich tat das gleiche, aber in meinem Fall gebe ich die Leinwand Gewicht und Höhe dynamisch mit Javascript. Dann gab ich die Höhe und Breite an Leinwand, wenn ich es erkläre. Das löst das Problem.