6

I'm doing to following:

  1. Generate an SVG document as a string
  2. Capture it in a blob: URL with new Blob and createObjectURL
  3. Create a fabric.Image object from it using fromURL
  4. In the fromURL callback, call canvas.add to add the new Image to the canvas

This is my code:

var svg = '<svg xmlns="http://www.w3.org/2000/svg" width="200" height = "200"><foreignObject width="100%" height="100%"><text xmlns = "http://www.w3.org/1999/xhtml" style = "font-size: 40px; color: #FFFFFF">Example</text></foreignObject></svg>';
var svgBlob = new Blob([svg], {type: 'image/svg+xml'});
var svgURL = window.URL.createObjectURL(svgBlob);
 fabric.Image.fromURL(svgURL,function(oIMG) {
   oIMG.crossOrigin = 'Anonymous';
   canvas.add(oIMG);
 });

Then I try getImageData:

var dataImage = context.getImageData(0,0,canvas.width,canvas.height).data;

In Chrome, this gives me the error:

Uncaught DOMException: Failed to execute 'getImageData' on 'CanvasRenderingContext2D': The canvas has been tainted by cross-origin data.

This is strange because I don't ever use any cross-origin URLs, only blob: URLs.

In Firefox it works perfectly. The problem appears to be specific to Chrome.

apsillers
  • 112,806
  • 17
  • 235
  • 239
IlFiltsin
  • 83
  • 8
  • 1
    Is the image hosted on a CORS friendly site? Also try changing `Anonymous` to `anonymous`. – GAntoine Jun 12 '18 at 19:10
  • I used anonymous and empty value, not working. What do you mean about CORS friendly? – IlFiltsin Jun 12 '18 at 19:15
  • 1
    Possible duplicate of [How to fix getImageData() error The canvas has been tainted by cross-origin data?](https://stackoverflow.com/questions/22097747/how-to-fix-getimagedata-error-the-canvas-has-been-tainted-by-cross-origin-data) –  Jun 13 '18 at 18:30
  • What is `oIMG`? If it's an `Image` object (i.e., an `` DOM object), what is its `src` property? – apsillers Jun 13 '18 at 19:08
  • @apsillers fabric.Image loads image from my url (generated by blob), and oIMG is new object after download image – IlFiltsin Jun 13 '18 at 19:17
  • @Amy what do you mean about possible duplicate? No one solution from your thread not working. – IlFiltsin Jun 13 '18 at 19:17
  • @CustomerExplorer it's a *possible* duplicate because it *appears* to be the same issue. It probably appears to be the same issue because it is. –  Jun 13 '18 at 19:18
  • @Amy I don't think this is a duplicate of that, because this case does not load from an external URL, but instead uses a local `blob:` URL (so `crossOrigin` won't have any significance, I think?). – apsillers Jun 13 '18 at 19:21
  • @apsillers console.log(oIMG) return – IlFiltsin Jun 13 '18 at 19:24
  • @apsillers, thank you for editing my topic. It's very nice! – IlFiltsin Jun 13 '18 at 19:56

1 Answers1

6

This is a known bug in Chrome: Canvas is tainted after drawing SVG including <foreignObject>. The current workaround is noted in that thread:

It seems that in the meantime the canvas is not tainted if the same picture has been loaded from a data URI.

This provides for a workaround.

You can turn your blob into a data: URL via FileReader like so:

var svg = '...';
var svgBlob = new Blob([svg], {type: 'image/svg+xml'});

var reader = new FileReader();
reader.readAsDataURL(svgBlob);

reader.onload = function(e) {
    var svgDataURL = e.target.result;
    fabric.Image.fromURL(svgDataURL, function(oIMG) {
        canvas.add(oIMG);
    });
}
Community
  • 1
  • 1
apsillers
  • 112,806
  • 17
  • 235
  • 239