2

Here's my code that deals with adding an image to the canvas. What this is doing is creating an instance of Uploadify, which uploads SVG files to the local [root]/uploads folder. Then it ads that image to three canvases of different sizes. At no point is the image referenced using an http:// address. All references to the image path are local relative.

    var folder = '/uploads';
    var fullpath = folder + '/' + $('input#canonical').val() + ".svg";
    $('#file_upload').uploadify({
        'uploader': '/uploadify/uploadify.swf',
        'script': '/uploadify/uploadify.php',
        'cancelImg': '/uploadify/cancel.png',
        'folder': folder,
        'fileExt': '*.svg',
        'fileDesc': 'SVG files',
        'scriptData':   {'rename': $('input#canonical').val() + ".svg"},
        'onAllComplete': function(){
            $('#upload-wrap').hide();

            var img = new Image();
            img.onload = function(){

                var ar = img.width / img.height;
                var swidth = ( ar >= 1 ) ? small : small * ar;
                var mwidth = ( ar >= 1 ) ? medium : medium * ar;
                var lwidth = ( ar >= 1 ) ? large : large * ar;

                var sheight = ( ar <= 1 ) ? small : small / ar;
                var mheight = ( ar <= 1 ) ? medium : medium / ar;
                var lheight = ( ar <= 1 ) ? large : large / ar;

                var sc = sCanvas.getContext('2d');    
                var mc = mCanvas.getContext('2d');   
                var lc = lCanvas.getContext('2d');    

                scObj.css({width:swidth, height: sheight});
                mcObj.css({width:mwidth, height: mheight});
                lcObj.css({width:lwidth, height: lheight});

                sc.drawImage(img,0,0,swidth,sheight);
                mc.drawImage(img,0,0,mwidth,mheight);
                lc.drawImage(img,0,0,lwidth,lheight);
            };
            img.src = fullpath;
        }
    });

When I try to call canvas.toDataUrl(), I get the Uncaught Error: SECURITY_ERR: DOM Exception 18 problem in the console. Is there a way to fix this? Let me know if you need more information.

Jake
  • 4,014
  • 8
  • 36
  • 54
  • 1
    Using file:// is probably the problem, see [http://stackoverflow.com/questions/2704929/uncaught-error-security-err-dom-exception-18][1] [1]: http://stackoverflow.com/questions/2704929/uncaught-error-security-err-dom-exception-18 – danwellman Apr 17 '12 at 08:16
  • @danwellman - By local, I meant local to the same server, not to my actual local machine. No outside http requests were made. – Jake Apr 17 '12 at 08:26
  • 1
    @Jake: then you mean "relative", not "local". – Andy E Apr 17 '12 at 14:45
  • @AndyE Yes, I did. Oops! – Jake Apr 17 '12 at 20:09

2 Answers2

4

At no point is the image referenced using an http:// address. All references to the image path are local.

Well that's the problem. You can't use local files in this way. Here's a bit on understanding the Canvas image security rules.

If a canvas is allowed to draw local files to itself then it could potentially draw a file that is on your local drive (private to you), get its imageData, and upload that file to a server, effectively stealing the image. We can't have that, so the "local files break origin-clean" rule is in place.

You can actually turn off that rule in Chrome:

C:\Users\theUser\AppData\Local\Google\Chrome\Application\chrome.exe --allow-file-access-from-files

But that should only be for debugging.

Simon Sarris
  • 62,212
  • 13
  • 141
  • 171
  • By local, I meant local to the server itself. Does your comment still apply? Could I fix it by making absolute references instead of relative references? – Jake Apr 17 '12 at 20:08
  • relative references ought to be fine as long as the url in question has a domain and protocol that is identical to the page that the JS is running on. Is there a discrepancy there? (I'd literally `console.log(fullpath)` to be sure) – Simon Sarris Apr 17 '12 at 23:12
2

This is the same problem as described here: Rasterizing an in-document SVG to Canvas

Basically, adding any SVG to a canvas taints the canvas and toDataURL() can no longer be called on it. Apparently, Firefox 12 fixes this, but Chrome has yet to fix it.

Community
  • 1
  • 1
Jake
  • 4,014
  • 8
  • 36
  • 54