Blob von DataURL?


85

Mit FileReader's readAsDataURL()kann ich beliebige Daten in eine Daten-URL umwandeln. Gibt es eine Möglichkeit, eine Daten-URL Blobmithilfe der integrierten Browser-APIs wieder in eine Instanz zu konvertieren ?

Antworten:


143

Benutzer Matt hat vor einem Jahr den folgenden Code vorgeschlagen ( Wie konvertiere ich dataURL in ein Dateiobjekt in Javascript? ), Der Ihnen helfen könnte

EDIT: Wie einige Kommentatoren berichteten, ist BlobBuilder vor einiger Zeit veraltet. Dies ist der aktualisierte Code:

function dataURItoBlob(dataURI) {
  // convert base64 to raw binary data held in a string
  // doesn't handle URLEncoded DataURIs - see SO answer #6850276 for code that does this
  var byteString = atob(dataURI.split(',')[1]);

  // separate out the mime component
  var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0]

  // write the bytes of the string to an ArrayBuffer
  var ab = new ArrayBuffer(byteString.length);

  // create a view into the buffer
  var ia = new Uint8Array(ab);

  // set the bytes of the buffer to the correct values
  for (var i = 0; i < byteString.length; i++) {
      ia[i] = byteString.charCodeAt(i);
  }

  // write the ArrayBuffer to a blob, and you're done
  var blob = new Blob([ab], {type: mimeString});
  return blob;

}

2
Hinweis: Laut MDN ist BlobBuilder jetzt veraltet. Keine Ahnung seit wann. (Ich weiß, dass dies eine ziemlich alte Frage und Antwort ist, nur um sie ein wenig auf dem neuesten Stand zu halten.) Stattdessen akzeptiert der Blob eine Reihe von Teilen als ersten Parameter seines Konstruktors.
Kiruse

8
Sie können den BlobBuilder als den Blob ersetzen. var blob = neuer Blob ([ab], {Typ: mimeString}); Blob zurückgeben;
Danil Chernokalov

4
Die doppelte Aufteilung scheint etwas verschwenderisch zu sein, da dies eine sehr große Zeichenfolge sein könnte.
Jesse Crossen

2
Welche Rolle spielt die Variable "ia" - ihr wird ein Wert zugewiesen, der jedoch niemals zur Bildung des Blobs verwendet wird. Warum?
Blaze

9
Blob der Baumeister? :)
Peter Wone

40

Wie @Adria Methode, aber mit Fetch API und nur kleiner [ caniuse? ]
Sie müssen nicht über den Mimetyp nachdenken, da der Blob-Antworttyp sofort funktioniert

Warnung: Kann gegen die Content Security Policy (CSP) verstoßen
... wenn Sie dieses Material verwenden

var url = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=="

fetch(url)
.then(res => res.blob())
.then(blob => console.log(blob))

Denken Sie nicht, dass Sie es kleiner machen könnten, ohne libs zu verwenden


Sehr elegant. Leider unterstützen Edge 13 und Safari "Fetch" nicht.
Alex_1948511

1
Es wird in Edge 14 und Safari 10.1
Endless

17
Asynchrone Version:const blob = await (await fetch(url)).blob();
Christian d'Heureuse

Funktioniert hervorragend, aber die Datei hat beim Lesen vom Server keine Erweiterung. Irgendwelche Gedanken?
Pauljeba

Der Server hat keine Blobs? node-fetchDosis haben jedoch ein Konzept von Blob, aber da es serverseitig ist, ist es ziemlich nutzlos. Außerdem haben Blobs keine Erweiterungen oder Dateinamen (es ist nur ein Container zum Speichern von Daten)
Endless

18
dataURItoBlob : function(dataURI, dataTYPE) {
        var binary = atob(dataURI.split(',')[1]), array = [];
        for(var i = 0; i < binary.length; i++) array.push(binary.charCodeAt(i));
        return new Blob([new Uint8Array(array)], {type: dataTYPE});
    }

input dataURI ist die Daten-URL und dataTYPE ist der Dateityp und gibt dann das Blob-Objekt aus


Das dataTYPEist eingebettet in dataURIund sollte daher wie in der ersten Antwort analysiert werden.
Noel Abrahams

dataURL2Blob stammt von meinem Plugin für den Bildprozess. Sie können diesen Link überprüfen. Ich kopiere einfach meinen eigenen Code. github.com/xenophon566/html5.upload/blob/master/js/…
Shawn Wu

12

XHR-basierte Methode.

function dataURLtoBlob( dataUrl, callback )
{
    var req = new XMLHttpRequest;

    req.open( 'GET', dataUrl );
    req.responseType = 'arraybuffer'; // Can't use blob directly because of https://crbug.com/412752

    req.onload = function fileLoaded(e)
    {
        // If you require the blob to have correct mime type
        var mime = this.getResponseHeader('content-type');

        callback( new Blob([this.response], {type:mime}) );
    };

    req.send();
}

dataURLtoBlob( 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==', function( blob )
{
    console.log( blob );
});

Scheint, das ist jetzt der beste Weg. Danke dir!
dizel3d

Funktioniert nicht in Safari - es wird ein Cross-Origin-Fehler ausgegeben, wenn die Seite von HTTPS geladen wird.
Martin Ždila

Die Frage ist Blob von DataURL?
Michal

3

Versuchen:

function dataURItoBlob(dataURI) {
    if(typeof dataURI !== 'string'){
        throw new Error('Invalid argument: dataURI must be a string');
    }
    dataURI = dataURI.split(',');
    var type = dataURI[0].split(':')[1].split(';')[0],
        byteString = atob(dataURI[1]),
        byteStringLength = byteString.length,
        arrayBuffer = new ArrayBuffer(byteStringLength),
        intArray = new Uint8Array(arrayBuffer);
    for (var i = 0; i < byteStringLength; i++) {
        intArray[i] = byteString.charCodeAt(i);
    }
    return new Blob([intArray], {
        type: type
    });
}

3

In modernen Browsern kann man den von Christian d'Heureuse vorgeschlagenen Liner in einem Kommentar verwenden:

const blob = await (await fetch(dataURI)).blob(); 

2

Erstellen Sie einen Blob mit der XHR-API :

function dataURLtoBlob( dataUrl, callback )
{
    var req = new XMLHttpRequest;

    req.open( 'GET', dataUrl );
    req.responseType = 'blob';

    req.onload = function fileLoaded(e)
    {
        callback(this.response);
    };

    req.send();
}

var dataURI = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=='

dataURLtoBlob(dataURI , function( blob )
{
    console.log( blob );
});


0

Verwenden Sie meinen Code, um dataURI in Blob umzuwandeln. Es ist einfacher und sauberer als andere.

function dataURItoBlob(dataURI) {
    var arr = dataURI.split(','), mime = arr[0].match(/:(.*?);/)[1];
    return new Blob([atob(arr[1])], {type:mime});
}

Können Sie erklären, warum Ihr Code nicht in ein int-Array konvertiert werden muss, während alle anderen dies tun?
Ameen


@Rikard was meinst du? es hat keinen Einfluss auf das Bild
Cuixiping

2
Dies funktioniert nur für einige grundlegende Dinge. Sie müssten + decodeURIComponent entkommen es zuerst die meisten Content-Encoding unterstützt dies lesen . Aus diesem Grund konvertieren andere einen String in ein int-Array, um den langsamen / hungrigen Funktionsaufruf decodeURIComponent / atob zu vermeiden, und konvertieren direkt in die Bytes
Endless

0

Da keine dieser Antworten base64- und non-base64-dataURLs unterstützt, basiert diese auf der gelöschten Antwort von vuamitom:

// from /programming/37135417/download-canvas-as-png-in-fabric-js-giving-network-error/
var dataURLtoBlob = exports.dataURLtoBlob = function(dataurl) {
    var parts = dataurl.split(','), mime = parts[0].match(/:(.*?);/)[1]
    if(parts[0].indexOf('base64') !== -1) {
        var bstr = atob(parts[1]), n = bstr.length, u8arr = new Uint8Array(n)
        while(n--){
            u8arr[n] = bstr.charCodeAt(n)
        }

        return new Blob([u8arr], {type:mime})
    } else {
        var raw = decodeURIComponent(parts[1])
        return new Blob([raw], {type: mime})
    }
}

Hinweis: Ich bin mir nicht sicher, ob es solche gibt andere dataURL-MIME-Typen gibt, die möglicherweise anders behandelt werden müssen. Aber bitte lassen Sie es mich wissen, wenn Sie es herausfinden! Es ist möglich, dass dataURLs einfach ein beliebiges Format haben können. In diesem Fall liegt es an Ihnen, den richtigen Code für Ihren speziellen Anwendungsfall zu finden.


-2

verwenden

FileReader.readAsArrayBuffer(Blob|File)

eher, als

FileReader.readAsDataURL(Blob|File)

2
Ich muss es auf unbestimmte Zeit als dataURL in localStorage speichern, damit die Verwendung des alternativen ArrayBufferPfads nicht funktioniert.
Shane Holloway
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.