Wie zeichnen Sie in hoher Auflösung auf Leinwand in Chrome? Und warum, wenn devicePixelRatio === webkitBackingStorePixelRatio Skalierung auf 2x verbessert die Auflösung?

8

Ich versuche, ein 300-dpi-Bild auf ein Leinwandobjekt zu zeichnen, aber in Chrome wird es in sehr schlechter Qualität angezeigt. Wenn ich den folgenden Code verwendet habe, hat es sich nicht verbessert, aber das lag daran, dass devicePixelRatio dasselbe war wie backingStoreRatio (beide waren 1 ).

Ich habe dann versucht, einige Verhältnisänderungen zu erzwingen und folgendes gefunden:

  • Wenn ich ratio in 2 geändert habe und den Skalierungscode zur Ausführung gezwungen habe, wird er in einer besseren Auflösung in die Zeichenfläche gezeichnet.
  • Wenn ich ratio auf etwas Größeres als 2 (zB 3 , 4 , 5 , 6 usw.) geändert habe, dann hatte es schlechte Auflösung!

Dies wurde alles auf einem Desktop-Computer getan.

Wie kann ich sicherstellen, dass die Zeichenfläche mit hoher Auflösung gezeichnet wird?

(Code von: Ссылка )

%Vor%

Wenn Sie nur die folgenden Änderungen vornehmen, werden Bilder mit hoher Auflösung erzeugt (warum?):

%Vor%

Wenn wir das obige auf ein Verhältnis von 3 ändern, ist es nicht mehr hochauflösend!

BEARBEITEN: Eine zusätzliche Beobachtung - sogar mit dem 2x-Verhältnis, während es eine bemerkenswert bessere Auflösung ist, ist es immer noch nicht so scharf wie das Bild in einem img -Tag)

    
Don Rhummy 02.10.2013, 17:23
quelle

2 Antworten

9

Der HTML5Rocks-Artikel, der mit der Frage verknüpft ist, macht die Dinge schwieriger als sie sein müssen, aber sie macht den gleichen grundlegenden Fehler wie andere Ressourcen, die ich gesehen habe (1 , 2 , 3 , 4 ). Diese Referenzen geben einige Variationen dieser Formel:

%Vor%

Die Formel ist falsch. Eine bessere Formel ist

%Vor%

Der Punkt ist, dass es nicht sinnvoll ist, eine Breite oder Höhe ( d. , die Differenz zweier Positionen) mit devicePixelRatio zu skalieren. Sie sollten immer nur eine absolute Position skalieren. Ich kann für genau diesen Punkt keine Referenz finden, aber ich denke, es ist offensichtlich, sobald Sie es verstanden haben.

Vorschlag.

Es gibt keine Möglichkeit, die physikalische Breite und Höhe eines Rechtecks ​​(in Gerätepixeln) aus seiner CSS-Breite und -Höhe (in geräteunabhängigen Pixeln) zu berechnen.

Beweis.

Angenommen, Sie haben zwei Elemente, deren Begrenzungsrechtecke in geräteunabhängigen Pixeln sind

%Vor%

Wenn nun devicePixelRatio 1.4 ist, werden die Elemente diese Gerätepixelrechtecke abdecken:

%Vor%

wo links, oben, rechts und unten mit devicePixelRatio multipliziert und auf die nächste Ganzzahl gerundet wurden (mit Math.round ()).

Sie werden feststellen, dass die beiden Rechtecke in geräteunabhängigen Pixeln, aber in Gerätepixeln unterschiedliche Breite haben. ▯

Testen.

Hier ist ein Codebeispiel zum Testen. Laden Sie es in einen Browser und zoomen Sie dann mit der Maus hinein und heraus. Die letzte Leinwand sollte immer scharfe Linien haben. Die anderen drei werden bei einigen Auflösungen verschwommen sein.

Getestet auf dem Desktop Firefox, IE, Edge, Chrome und Android Chrome und Firefox. (Hinweis: Dies funktioniert nicht bei JSfiddle , da getBoundingClientRect dort falsche Werte zurückgibt.)

%Vor%     
Buster 06.02.2016 18:07
quelle
3

Ein Trick, den Sie verwenden könnten, besteht darin, die Leinwandbreite und -höhe auf die Pixelhöhe und -breite des Fotos zu setzen und dann mit CSS die Größe des Bildes zu ändern. Unten ist ein Sudo-Code-Beispiel.

%Vor%

Dann können Sie entweder width & amp; Höheneinstellung oder eine 3D-Transformation.

%Vor%

oder

%Vor%

Ich schlage vor, dass Sie die 3D-Transformation verwenden, denn wenn Sie 3D-Transformationen verwenden, werden die Bilddaten des Elements auf die GPU kopiert, so dass Sie sich nicht um Qualitätseinbußen kümmern müssen.

Ich hoffe, das hilft!

    
hyphnKnight 29.05.2014 16:06
quelle