简体   繁体   English

同步将Blob转换为二进制字符串

[英]Convert Blob to binary string synchronously

I'm trying to put image in clipboard when user copies canvas selection: 当用户复制画布选择时,我正在尝试将图像放入剪贴板:

画布选择

So I thought the right way would be to convert canvas tu dataURL, dataURL to blob and blob to binary string. 所以我认为正确的方法是将canvas tu dataURL,dataURL转换为blob和blob转换为二进制字符串。

Theoretically it should be possible to skip the blob, but I don't know why. 理论上应该可以跳过blob,但我不知道为什么。

So this is what I did: 所以这就是我做的:

  function copy(event) {
    console.log("copy");
    console.log(event);

    //Get DataTransfer object
    var items = (event.clipboardData || event.originalEvent.clipboardData);
    //Canvas to blob
    var blob = Blob.fromDataURL(_this.editor.selection.getSelectedImage().toDataURL("image/png"));
    //File reader to convert blob to binary string
    var reader = new FileReader();
    //File reader is for some reason asynchronous
    reader.onloadend = function () {
      items.setData(reader.result, "image/png");
    }
    //This starts the conversion
    reader.readAsBinaryString(blob);

    //Prevent default copy operation
    event.preventDefault();
    event.cancelBubble = true;
    return false;
  }
  div.addEventListener('copy', copy);

But when the DataTransfer object is used out of the paste event thread the setData has no longer any chance to take effect. 但是当在paste事件线程之外使用DataTransfer对象时, setData不再有任何生效的机会。

How can I do the conversion in the same function thread? 如何在同一个函数线程中进行转换?

Here is a hacky-way to get you synchronously from a blob to it's bytes. 这是一种从blob到它的字节同步的hacky-way。 I'm not sure how well this works for any binary data. 我不确定它对任何二进制数据的效果如何。

function blobToUint8Array(b) {
    var uri = URL.createObjectURL(b),
        xhr = new XMLHttpRequest(),
        i,
        ui8;

    xhr.open('GET', uri, false);
    xhr.send();

    URL.revokeObjectURL(uri);

    ui8 = new Uint8Array(xhr.response.length);

    for (i = 0; i < xhr.response.length; ++i) {
        ui8[i] = xhr.response.charCodeAt(i);
    }

    return ui8;
}

var b = new Blob(['abc'], {type: 'application/octet-stream'});
blobToUint8Array(b); // [97, 98, 99]

You should consider keeping it async but making it two-stage, though, as you may end up locking up the browser. 你应该考虑让它保持异步但是让它成为两个阶段,因为你最终可能会锁定浏览器。

Additionally, you can skip Blobs entirely by including a binary-safe Base64 decoder, and you probably don't need to go via Base64 AND Blob , just one of them. 此外,您可以通过包含二进制安全的Base64解码器完全跳过Blob ,您可能不需要通过Base64 AND Blob ,只需其中一个。

Blob can be converted to binary string by getting Blob as d ataURI and then applying atob . 通过将Blob作为d ataURI然后应用atob可以将Blob转换为二进制字符串。 This, however, again [requires FileReader][3] . 然而,这又[需要FileReader][3] In my case, it's best to skip the blob alltogether: 在我的情况下,最好完全跳过blob:

//Canvas to binary
var data = atob(
  _this.editor.selection.getSelectedImage()  //Canvas
  .toDataURL("image/png")                    //Base64 URI
  .split(',')[1]                             //Base64 code
);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM