Closed SkepticaLee closed 5 years ago
The security error refers to line 13715 of paperjs version 0.11.5, which is the line:
var dstData = dstContext.getImageData(offset.x, offset.y, srcCanvas.width, srcCanvas.height)
This would normally be triggered by a cross origin, which is not the case here.
Hi, as you have guessed, it is a CORS issue.
Problematic modes are those which are not natively supported by your browser and thus need access to the image data. And this image data access is by default prevented by CORS.
Here is another issue related to this problem.
To enable CORS access from Paper.js
, you need to set the crossOrigin property on your Raster
instance.
new Raster({
crossOrigin: 'anonymous',
source: 'http://assets.paperjs.org/images/marilyn.jpg'
});
Here is a Sketch showing all blend modes in action.
I thought it was a CORS issue as well, but then the images on http://paperjs.org/reference/raster/#raster shouldn't show at all to begin with. It is only when the blendMode is manipulated tha tth einmage disappears. Try this in the box on that page:
var raster = new Raster({
crossOrigin: 'anonymous',
source: 'http://assets.paperjs.org/images/marilyn.jpg',
position: view.center
});
raster.scale(0.5);
raster.rotate(10);
raster.blendMode = 'negation';
BTW in your sketch you should have 5 rows, not 4, to show the "negation" effect.
Sorry about the missing blend mode in the sketch :)
Your seing this issue on http://paperjs.org/reference/raster/#raster because when you load the page, the image is drawn in the canvas without CORS attribute and that result in a tainted canvas.
As soon as you draw into a canvas any data that was loaded from another origin without CORS approval, the canvas becomes tainted. A tainted canvas is one which is no longer considered secure, and any attempts to retrieve image data back from the canvas will cause an exception to be thrown.
So when you change the code snippet and click the run button, despite you use CORS attribute, the canvas is still tainted and this produces an error. This can be reproduced in Sketch by loading two images consecutively. First without, then with CORS attribute.
I'm not sure if we can / must do something about that. Is it user responsability to never load an image in the canvas without taking care of CORS if he wants to manipulate image data later ? @lehni & @sapics, what do you think ?
Well, you should do something about it, otherwise it looks like the page is broken and/or paperjs doesn't work...
Besides, if you leave out the crossOrigin property in your sketch, the modes "normal", "hard-light", "difference" and "color" still work, even though the latter three are not native blend modes. Something else is going on here.
Try this in the sketch to see what happens with the position, despite CORS being set:
function displayImage(point, blendMode) {
new Raster({
source: 'http://assets.paperjs.org/images/marilyn.jpg',
crossOrigin: 'anonymous',
position: point,
scaling: 0.25,
onLoad: function() {this.blendMode = blendMode;}
});
new PointText({
point: point + [0,80],
content: blendMode,
justification: 'center',
fillColor: 'black'
});
}
new Path.Rectangle({
rectangle: view.bounds,
fillColor: 'orange'
});
var modes = [
'normal', 'multiply', 'screen', 'overlay', 'soft-light',
'hard-light', 'color-dodge', 'color-burn', 'darken', 'lighten',
'difference', 'exclusion', 'hue', 'saturation', 'luminosity',
'color', 'add', 'subtract', 'average', 'pin-light', 'negation'
];
for (var i = 0; i < 25; i++) displayImage(new Point(100 + (i % 6) * 150, 100 + Math.floor (i / 6) * (i % 6) * 135), modes[i]);
About your last example, I think it is a problem with your position calculation. Is that what you were trying to do ?
You are right, I haven't realized that the error stopped the script execution. So the least we can do is catch this error and provide an help message. Here is an updated Sketch precising which mode is natively supported.
@sasensi do these errors show up in the console? If so, what do they say? And do we really need to catch them and print a message?
@lehni, not only error show up in the console, but it crashes script execution. Here is a Sketch demonstrating it.
Uncaught SecurityError: Failed to execute 'getImageData' on 'CanvasRenderingContext2D': The canvas has been tainted by cross-origin data.
@sasensi I think in that case we shouldn't add special code to emit warnings... We can just direct questions to this issue instead? Are you OK with closing this MR without merging?
@lehni if you think that's the right way to go, it's fine for me. I closed the PR.
I close this issue because the cause of the problem can't be fixed in the library.
As a final note and as mentioned earlier in this discussion, any image loaded from an external source should be loaded with the crossOrigin
attribute set, in order to avoid tainted canvas errors.
var raster = new Raster({
crossOrigin: 'anonymous',
source: 'http://assets.paperjs.org/images/marilyn.jpg'
});
Using the example in the documentation for Rasters:
var url = 'http://assets.paperjs.org/images/marilyn.jpg'; raster = new Raster(url);
// If you create a Raster using a url, you can use the onLoad // handler to do something once it is loaded: raster.onLoad = function() { console.log('The image has loaded.'); raster.blendMode = "add"; };
This causes the image to disappear and a message in red appears on the console:
SecurityError: The operation is insecure.
Blend modes that appear to do this are e.g.: add, subtract, negation, average, pin-light
Blend modes that work as expected are e.g:
normal, screen, multiply, overlay, soft-light, hard-light, color-burn, color-dodge,
In my applications the image is translated into the center of the canvas, and its position is read out to be [0, 0].
Is this a bug?