Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does this SVG-holding `blob:` URL taint the canvas in Chrome?

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.

like image 289
IlFiltsin Avatar asked Jun 12 '18 18:06

IlFiltsin


People also ask

What does <SVG> mean in HTML?

<svg> acts as the art board where all the different shapes and figures are drawn. So, its height and width indicates the size in which the whole drawing needs to be enclosed.

Can you make a circle in CSS without SVG?

And, if all you need is a circle, we could probably lean on CSS without SVG at all. Any box element can become a circle or ellipse with border-radius. …but more on that later. Thanks to SVG’s <path> tag, we can create any kind of shape. It is like drawing with a pencil or pen.

How to create multiple overlapping circles like this in SVG?

Let’s create multiple overlapping circles like this: <svg> acts as the art board where all the different shapes and figures are drawn. So, its height and width indicates the size in which the whole drawing needs to be enclosed. If some part of figure is out of bounds of the SVG’s size, then that part will be truncated.

What is a blob?

Blobs are the smooth, random, jelly-like shapes that have a whimsical quality and are just plain fun. They can be used as illustration elements and background effects on the web.


1 Answers

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);
    });
}
like image 133
apsillers Avatar answered Oct 11 '22 22:10

apsillers