最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Convert Blob to binary string synchronously - Stack Overflow

programmeradmin5浏览0评论

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.

Theoretically it should be possible to skip the blob, but I don't know why.

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.

How can I do the conversion in the same function thread?

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.

Theoretically it should be possible to skip the blob, but I don't know why.

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.

How can I do the conversion in the same function thread?

Share Improve this question asked Nov 29, 2014 at 23:41 Tomáš ZatoTomáš Zato 53.2k63 gold badges308 silver badges822 bronze badges 3
  • parameter order in setData should be reversed -> items.setData("image/png", reader.result) – belzebu Commented Jul 16, 2015 at 7:39
  • I have to admit that I'm really struggling to get the canvas into the clipboardData object and paste it let's say in MS Outlook message or elsewhere. Tomas, could you please outline what was your final solution to copy canvas into clipboard. I've tried nearly everything I could either using the setData("image/png"...) or items.filed.add(file) etc.. what should be the value to be passed to setData("image/url", ??) ? Thank you. – belzebu Commented Jul 17, 2015 at 2:31
  • @belzebu Unless something changes, I have bad news. I posted question subsequent to this one and it's still not answered because it's simply not possible: stackoverflow./q/27262879/607407 – Tomáš Zato Commented Jul 21, 2015 at 19:18
Add a ment  | 

2 Answers 2

Reset to default 8

Here is a hacky-way to get you synchronously from a blob to its bytes. 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.

Blob can be converted to binary string by getting Blob as dataURI and then applying atob. This, however, again requires FileReader. In my case, it's best to skip the blob alltogether:

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

评论列表(0)

  1. 暂无评论