Blob từ DataURL?


92

Sử dụng FileReader's, readAsDataURL()tôi có thể chuyển đổi dữ liệu tùy ý thành URL dữ liệu. Có cách nào để chuyển đổi lại một URL dữ liệu thành một Blobphiên bản bằng cách sử dụng apis trình duyệt nội trang không?

Câu trả lời:


151

Người dùng Matt đã đề xuất đoạn mã sau đây một năm trước ( Làm thế nào để chuyển đổi dataURL sang đối tượng tệp trong javascript? ), Mã này có thể giúp bạn

CHỈNH SỬA: Như một số người bình luận đã báo cáo, BlobBuilder đã không còn được dùng cách đây một thời gian. Đây là mã được cập nhật:

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;

}

4
Việc phân tách trùng lặp có vẻ hơi lãng phí, vì đây có thể là một chuỗi rất lớn.
Jesse Crossen

2
Vai trò của biến "ia" là gì - nó được gán một giá trị nhưng không bao giờ được sử dụng để hình thành đốm màu. Tại sao?
Blaze

1
Blaze, Ward: ia là một khung nhìn của vùng đệm. Vì vậy, khi bạn đặt mỗi byte trong ia, nó đang ghi vào bộ đệm. Nếu không có vòng lặp trên ia, bộ đệm sẽ hoàn toàn trống.
Mat

1
Làm cách nào để tìm câu trả lời SO # 6850276?
BT

1
@BT: Tôi đoán dự định là stackoverflow.com/a/30407840/271577 (lưu ý rằng URL được chuyển hướng bao gồm "# 6850276").
Brett Zamir

50

Giống như phương thức @Adria nhưng với Fetch api và nhỏ hơn [ caniuse? ]
Không phải nghĩ về mimetype vì kiểu phản hồi blob chỉ hoạt động hiệu quả

Cảnh báo: Có thể vi phạm Chính sách bảo mật nội dung (CSP)
... nếu bạn sử dụng nội dung đó

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

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

Đừng nghĩ rằng bạn có thể làm điều đó nhỏ hơn bất kỳ điều này mà không cần sử dụng lib's


1
Rất thanh lịch. Thật không may, cạnh 13 và safari không hỗ trợ "tìm nạp".
alex_1948511

2
Nó được hỗ trợ trong edge 14 và safari 10.1
Endless

19
Phiên bản không đồng bộ:const blob = await (await fetch(url)).blob();
Christian d'Heureuse

Hoạt động tốt, nhưng tệp không có phần mở rộng khi đọc từ máy chủ. Có suy nghĩ gì không?
pauljeba

1
Vấn đề lớn hơn của điều này fetchlà nó buộc phải có một API không đồng bộ.
Dennis C

19
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});
    }

dữ liệu đầu vàoURI là URL dữ liệu và dataTYPE là loại tệp và sau đó xuất đối tượng blob


1
Các dataTYPEđược nhúng vào trong dataURIvà do đó cần được phân tích như trong câu trả lời đầu tiên.
Noel Abrahams

dataURL2Blob đến từ plugin của tôi cho quá trình xử lý hình ảnh, bạn có thể xem liên kết này. Tôi chỉ sao chép mã của riêng tôi. github.com/xenophon566/html5.upload/blob/master/js/…
Shawn Wu

12

Phương pháp dựa trên XHR.

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 );
});

Có vẻ, đây là cách tốt nhất bây giờ. Cảm ơn bạn!
dizel3d ngày

Sẽ không hoạt động trong Safari - nó sẽ gây ra lỗi nguồn gốc chéo nếu trang được tải từ HTTPS.
Martin Ždila

Câu hỏi là Blob từ DataURL?
Michal


3

thử:

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
    });
}

2

Tạo một đốm màu bằng cách sử dụng API XHR :

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

Sử dụng mã của tôi để chuyển đổi dataURI thành blob. Nó đơn giản và sạch sẽ hơn những cái khác.

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

Bạn có thể giải thích tại sao mã của bạn không cần chuyển đổi thành mảng int trong khi mọi người khác đang làm điều đó?
Ameen


@Rikard ý bạn là gì? nó không ảnh hưởng đến bất kỳ hình ảnh
cuixiping

2
Điều này chỉ hoạt động đối với một số công cụ cơ bản. Trước tiên, bạn cần phải thoát + giải mãURIComponent nó để hỗ trợ hầu hết các mã hóa nội dung đọc nội dung này . Đó là lý do tại sao những người khác chuyển đổi một chuỗi để mảng int để tránh những chức năng decodeURIComponent / atob chậm / đói cuộc gọi và chuyển đổi trực tiếp các byte
Endless

0

Vì không có câu trả lời nào trong số này hỗ trợ dataURL của base64 và không phải base64, đây là một câu trả lời dựa trên câu trả lời đã xóa của 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})
    }
}

Lưu ý: Tôi không chắc liệu có các loại mime dataURL khác có thể phải được xử lý theo cách khác hay không. Nhưng hãy cho tôi biết nếu bạn phát hiện ra! Có thể dữ liệuURL có thể có bất kỳ định dạng nào họ muốn và trong trường hợp đó, bạn có thể tìm đúng mã cho trường hợp sử dụng cụ thể của mình.


-2

sử dụng

FileReader.readAsArrayBuffer(Blob|File)

hơn là

FileReader.readAsDataURL(Blob|File)

2
Tôi phải lưu trữ nó dưới dạng DataURL trong một khoảng thời gian không xác định trong localStorage, vì vậy việc sử dụng ArrayBufferđường dẫn thay thế sẽ không hoạt động.
Shane Holloway
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.