Ich habe versucht, einen HTML5-Bild-Uploader wie den auf der Mozilla Hacks- Website erneut zu implementieren , aber das funktioniert mit WebKit-Browsern. Ein Teil der Aufgabe besteht darin, eine Bilddatei aus dem canvas
Objekt zu extrahieren und zum Hochladen an ein FormData- Objekt anzuhängen .
Das Problem ist, dass das FormData-Objekt zwar canvas
die toDataURL
Funktion hat, eine Darstellung der Bilddatei zurückzugeben, jedoch nur Datei- oder Blob-Objekte von der Datei-API akzeptiert .
Die Mozilla-Lösung verwendete die folgende Nur-Firefox-Funktion für canvas
:
var file = canvas.mozGetAsFile("foo.png");
... was in WebKit-Browsern nicht verfügbar ist. Die beste Lösung, die ich mir vorstellen kann, besteht darin, eine Möglichkeit zu finden, einen Daten-URI in ein Dateiobjekt zu konvertieren, von dem ich dachte, dass es Teil der Datei-API ist, aber ich kann für mein ganzes Leben nichts finden, um dies zu tun.
Ist es möglich? Wenn nicht, Alternativen?
Vielen Dank.
quelle
Antworten:
Nachdem ich mit ein paar Dingen herumgespielt hatte, gelang es mir, dies selbst herauszufinden.
Zunächst wird eine dataURI in einen Blob konvertiert:
Von dort aus ist es einfach, die Daten an ein Formular anzuhängen, sodass sie als Datei hochgeladen werden:
quelle
POST
oderPUT
zu S3 konstruieren ?ArrayBuffer
, der dann in dieBlobBuilder
Instanz geschrieben wird.var file = new File( [blob], 'canvasImage.jpg', { type: 'image/jpeg' } ); fd.append("canvasImage", file);
BlobBuilder und ArrayBuffer sind jetzt veraltet. Hier ist der Code des obersten Kommentars, der mit dem Blob-Konstruktor aktualisiert wurde:
quelle
array=[]; array.length=binary.length;
...array[i]=bina
... usw. Das Array ist also vorab zugewiesen. Es erspart einen Push (), der das Array bei jeder Iteration erweitern muss, und wir verarbeiten hier möglicherweise Millionen von Elementen (= Bytes), also ist es wichtig.Dieser funktioniert in iOS und Safari.
Sie müssen die ArrayBuffer-Lösung von Stoive verwenden, können jedoch nicht BlobBuilder verwenden, wie vava720 angibt. Hier ist das Mashup von beiden.
quelle
Firefox verfügt über die Methoden canvas.toBlob () und canvas.mozGetAsFile () .
Andere Browser jedoch nicht.
Wir können Dataurl von Canvas abrufen und dann Dataurl in Blob-Objekt konvertieren.
Hier ist meine
dataURLtoBlob()
Funktion. Es ist sehr kurz.Verwenden Sie diese Funktion mit FormData, um Ihre Zeichenfläche oder Daten-URL zu verarbeiten.
Beispielsweise:
Sie können auch eine
HTMLCanvasElement.prototype.toBlob
Methode für einen Browser ohne Gecko-Engine erstellen .Funktioniert jetzt
canvas.toBlob()
für alle modernen Browser, nicht nur für Firefox. Zum Beispiel:quelle
Mein bevorzugter Weg ist canvas.toBlob ()
Aber hier ist noch eine andere Möglichkeit, base64 mit fetch ^^ in einen Blob umzuwandeln.
quelle
XMLHttpRequest
da Daten-URL nur eine URL ist. Sie können Ajax verwenden, um diese Ressource abzurufen, und Sie haben die Möglichkeit, selbst zu entscheiden, ob Sie sie als Blob, Array-Puffer oder Text verwenden möchtenblob:
unddata:
nicht universell von allen holen Implementierungen unterstützt. Wir verwenden diesen Ansatz, da wir wissen, dass wir uns nur mit mobilen Browsern (WebKit) befassen werden, Edge jedoch keine Unterstützung bietet: developer.mozilla.org/en-US/docs/Web/API/…Dank @Stoive und @ vava720 habe ich beide auf diese Weise kombiniert, ohne den veralteten BlobBuilder und ArrayBuffer zu verwenden
quelle
Der sich entwickelnde Standard scheint canvas.toBlob () zu sein, nicht canvas.getAsFile (), wie Mozilla zu erraten riskierte.
Ich sehe noch keinen Browser, der dies unterstützt :(
Danke für diesen tollen Thread!
Außerdem sollte jeder, der versucht, die akzeptierte Antwort zu erhalten, mit BlobBuilder vorsichtig sein, da ich finde, dass die Unterstützung begrenzt ist (und einen Namespace aufweist):
Haben Sie die Polyfüllung einer anderen Bibliothek für BlobBuilder verwendet?
quelle
canvas.toBlob()
- es scheint viel angemessener alsgetAsFile
.BlobBuilder
scheinen zugunsten vonBlob
kann ohne den try catch verwendet werden.
Vielen Dank an check_ca. Gute Arbeit.
quelle
Die ursprüngliche Antwort von Stoive kann leicht behoben werden, indem die letzte Zeile geändert wird, um Blob aufzunehmen:
quelle
Hier ist eine ES6-Version von Stoives Antwort :
Verwendungszweck:
quelle
Vielen Dank! @steovi für diese Lösung.
Ich habe die ES6-Version unterstützt und von unescape zu dataURI geändert (unescape ist veraltet).
quelle
mach es einfach: D.
quelle
toDataURL gibt Ihnen eine Zeichenfolge und Sie können diese Zeichenfolge in eine versteckte Eingabe einfügen.
quelle
<input type=hidden value="data:..." />
hochladen (was auch der<input type="file" />
Fall ist ), sondern die Dateidaten hochladen (wie dies der Fall ist, außer dass Sie dievalue
Eigenschaft für diese nicht festlegen dürfen ).Ich hatte genau das gleiche Problem wie Ravinder Payal und habe die Antwort gefunden. Versuche dies:
quelle
window.open(canvas.toDataURL("image/jpeg"))