2014-04-17 8 views
11

In einer clientseitigen eigenständigen JS-Anwendung versuche ich es so zu machen, dass ich ToDataURL() auf einer Leinwand aufrufen kann, auf der ich habe zeichnete einige Bilder, die durch eine URL spezifiziert wurden. Dh ich kann in eine Textbox die URL zu jedem Bild eingeben (gehostet auf, sagen wir, imgur), das ich auf der Leinwand zeichnen möchte, auf einen "Zeichnen" -Button klicken und es auf der Leinwand zeichnen. Der Endanwender sollte in der Lage sein, ihren endgültigen Render als einzelnes Bild zu speichern, dafür benutze ich toDataURL().Zeichnen von Bildern in Canvas mit img.crossOrigin = "Anonymous" funktioniert nicht

Wie auch immer, bis sie tatsächlich beheben, dass lästige "Operation ist unsicher" Fehler (gee, werden Sie dem Endbenutzer sagen, was sie können und nicht mit ihren eigenen Daten tun?) Ich folgte einem Workaround, sagte Fügen Sie das Bild dem DOM hinzu und legen Sie die Eigenschaft crossOrigin auf "Anonmyous" fest und zeichnen Sie es dann auf die Zeichenfläche.

Hier ist eine volle Arbeits vereinfachte Version von meinem Code (aber in Wirklichkeit gibt es viele weitere Funktionen sein):

<!DOCTYPE html5> 
<html> 
<head> 
<style> 
#canvas {border:10px solid green;background-color:black;} 
#imgbox {border:2px solid black;} 
</style> 
</head> 
<body> 
<canvas id="canvas" width=336 height=336></canvas> 
<br><br> 
<input size=60 id="imgbox"> 
<input type="submit" value="Draw" onclick=draw()> 
<script> 
function draw() { 
    var canvas = document.getElementById("canvas"); 
    var context = canvas.getContext("2d"); 
    var img = new Image(); 
    img.src = document.getElementById("imgbox").value; 
    img.crossOrigin = "Anonymous"; 
    context.drawImage(img, 40, 40); 
} 
</script> 
</body> 
</html> 

Ohne die img.crossOrigin = "Anonymous"; Linie, konnte ich Eingang http://i.imgur.com/c2wRzfD.jpg in das Textfeld und ziehen klicken und es würde Arbeit. Sobald ich jedoch diese Zeile hinzugefügt habe, ist das Ganze zerbrochen und es wird überhaupt nicht mehr auf die Leinwand gezogen.

Was muss ich ändern, um das Problem zu beheben? Ich muss wirklich in der Lage sein, die Funktionalität für den Endbenutzer zu implementieren, um ihr endgültiges Bild zu speichern, und es ist extrem ärgerlich, dass die Leute, die die html5-Spezifikation geschrieben haben, diesen Fehler absichtlich eingeführt haben.

Antwort

27

Sie müssen die CORS Anfrage vor die src-Set - tauschen nur die Linien in:

img.crossOrigin = "Anonymous"; 
img.src = document.getElementById("imgbox").value; 

Sie werden auch ein onload-Handler zu dem Bild hinzufügen müssen als Lade asynchron:

img.onload = function() { 
    context.drawImage(this, 40, 40); 
    // call next step in your code here, f.ex: nextStep(); 
}; 
img.crossOrigin = "Anonymous"; 
img.src = document.getElementById("imgbox").value; 
+0

Ja! Das hat den Trick gemacht. Vielen Dank! – Joey

+0

Warte, jetzt funktioniert es nur mit einigen Bildern. Bilder von imgur arbeiten, aber einige zufällige Bilder aus der Google-Bildersuche werden immer noch nicht auf die Leinwand gezeichnet. Zum Beispiel wird http://icons.iconarchive.com/icons/yellowicon/game-stars/256/Mario-icon.png überhaupt nicht gezeichnet. Irgendeine Idee warum? – Joey

+3

@Joey Sie können * nur * CORS-Nutzung anfordern, der Server kann die Anfrage ablehnen, die das Laden des Images zum Scheitern bringt. Sie müssen überprüfen, welche Server zulassen und welche nicht. Für diejenigen, die CORS nicht zulassen wollen, entfernen Sie einfach die Anfrage (crossOrigin line). Bei Bildern, die Sie nicht mit der CORS-Anfrage laden können, müssen Sie sie auf Ihren eigenen Server kopieren (wie auf der Seite) oder auf einen anderen Server verschieben, der die Verwendung von CORS erlaubt. (hoffe, dass das Sinn macht) – K3N

1

Wenn die Serverberechtigung erfordert werden die Bilder der Wert sollte zugreifen:

img.crossOrigin = "Use-Credentials"; 

Andernfalls gibt der Browser nach dem Empfang von HTTP 401 auf.