2017-04-27 6 views
1

Ich habe diese Frage auf Stackoverflow gesehen, aber ich habe keine Antwort gefunden - alle vorgeschlagenen Lösungen funktionieren einfach nicht für mich.Wie man mit Qualitätsverlust mit Canvas drawImage umgehen kann?

Problem: Wenn ich ein base64-codiertes SVG als src zur Bildverarbeitung übergebe, sieht es so klar aus wie das ursprüngliche SVG-Bild. Aber wenn ich dieses Bild nehmen würde und es verwende, in Leinwand (via context.drawImage) - es wäre eine worser Qualität: enter image description here

Die Frage ist - wie kann ich svg-basierte Bild in Leinwand zeichnen welches wird wie originalbild aussehen?

Was habe ich bisher versucht. Der beschriebene Ansatz here (re-iteratives Downsampling) funktioniert bei mir nicht. Der andere advise (um 0,5 zu den Dimensionen hinzuzufügen) hat die Situation außerdem nicht gespeichert. Spielen mit imageSmoothingEnabled - immer noch kein Glück.

Hier the codepen zur Erzeugung dieser besonderen Screenshot verwendet:

let toBase64 = (svg) => { 
    let serialized = new XMLSerializer().serializeToString(svg); 
    let base64prefix = "data:image/svg+xml;base64," 
    let enc = base64prefix + btoa(serialized); 
    return enc; 
} 

let copySvg = (svg, img) => { 
    let enc = toBase64(svg); 
    img.src = enc; 
} 

let copyImg = (img, canvas) => { 
    context = canvas.getContext("2d"); 
    context.drawImage(img, 0, 0, 200.5, 200.5); 
} 

let main =() => { 
    let svg = document.getElementById("svg"); 
    let img = document.getElementById("img"); 
    let canvas = document.getElementById("canvas"); 
    copySvg(svg, img); 
    copyImg(img, canvas); 
} 

window.onload = main; 
+1

Die Antwort von severla ist korrekt, Sie befinden sich wahrscheinlich auf einem Monitor mit hoher Auflösung. Unzusammenhängend, aber immer noch wichtig, müssen Sie warten, bis Ihr Bild geladen ist, bevor Sie es auf der Leinwand zeichnen konnten (Sie haben für mich nicht funktioniert), und nur Chrome unterstützt das Zeichnen von Svg ohne und absoluten Höhe und Breite Attribut. [Fester Stift] (http://codepen.io/anon/pen/MmJXXO) – Kaiido

Antwort

3

Die SVG und Bild werden implizit bei hohen DPI gezogen, aber Sie müssen explizit diesen Fall für die Leinwand handhaben.

Wenn Ihr Gerät window.devicePixelRatio === 2 hat, werden Sie ein viel schärferes Bild sehen, wenn Sie Leinwandgröße erhöhen und drawImage aktualisieren anzupassen:

<!-- Change this --> 
<canvas id="canvas" width="200" height="200"></canvas> 
<!-- to --> 
<canvas id="canvas" width="400" height="400"></canvas> 

Und:

// change this: 
context.drawImage(img, 0, 0, 200.5, 200.5); 
// to: 
context.drawImage(img, 0, 0, 400, 400); 

Forked codepen

Weitere Details zu window.devicePixelRatio (und Canvas backingStorePixelRatio) finden Sie im Artikel html5rocks unter High DPI Canvas

+0

korrekt, aber 'backingStorePixelRatio' wurde veraltet und sogar aus Implementierungen entfernt (außer von Safari, unter einem Präfix). – Kaiido

+0

hatte ich die Möglichkeit mehrere Male zu upvoten Ich hätte es gerade getan, danke! – shabunc

Verwandte Themen