Skip to content

capturing images and canvas with loaded images from other origin #103

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
chloeng opened this issue Jun 1, 2012 · 11 comments
Closed

capturing images and canvas with loaded images from other origin #103

chloeng opened this issue Jun 1, 2012 · 11 comments
Labels

Comments

@chloeng
Copy link

chloeng commented Jun 1, 2012

Hi Niklas,

Thank you so much for such wonderful code. It is such a great tool to solve my scenario. It worked fine in the beginning during local testing, but I encountered some issues while trying to deploy to our development server. The issues are:

  1. Need a proxy to access content from other domain/origin: I solved this by creating my own Java proxy (converted from the Python code). Seems to be working fine for images with tag.
  2. Encountered this issue for elements in my code which contains images loaded from other domain: [Unable to get image data from canvas because the canvas has been tainted by cross-origin data]. Is it due to the fact that the canvas element in my code contains drawn images from other domain/origin? Can this be solved? I have tried to set the header for "Access-Control-Allow-Origin" but seems like this won't solve the issue.

Have been searching for the solution for Issue 2 online for days but to no avail.

Hopefully you can enlighten me with a solution for this.

Thanks a lot.

@niklasvh
Copy link
Owner

niklasvh commented Jun 1, 2012

If you use a proxy, the images should load fine assuming you are sending them base64/jsonp or with CORS headers. Are you using SVG images by any chance? Any sort of SVG image, even inline ones, taint the canvas with webkit/FF prior to version 12.

@chloeng
Copy link
Author

chloeng commented Jun 4, 2012

Hi Niklas,

I hv run some experiments to identify the problem:

    function loadImages(sources, callback) {
        var images = {};
        var loadedImages = 0;
        var numImages = 0;
        for(var src in sources) {
          numImages++;
        }
        for(var src in sources) {
        images[src] = new Image();
        images[src].onload = function() {
        if(++loadedImages >= numImages) {
            callback(images);
        }
      };
      images[src].src = sources[src];
    }
    }

    window.onload = function(images) {
        var canvas = document.getElementById("myCanvas");
        var context = canvas.getContext("2d");

        var sources = {
          img1: "dog_ed.jpg",
          img2: "dog.jpg"
        };

        loadImages(sources, function(images) {
            context.drawImage(images.img1, 20, 20, 75, 75);
            context.drawImage(images.img2, 105, 20, 75, 75);
        });

        canvasRecord = $('body').html2canvas();
    };

The above is a javascript on the head section, and the following is the body section of my page:
`

`

This piece of code works fine, using the default proxy settings from your code and also using my own pre-defined Java proxy on my server. However, when I change the img2: "dog.jpg" to img2: "http://html2canvas.hertzen.com/tests/image.jpg", the screenshot returns the top image(from img element:image.jpg) with empty canvas with only the border line as well as the error [Unable to get image data from canvas because the canvas has been tainted by cross-origin data.]

I hope I depict the problem clearly. Thank you for your time.

@niklasvh
Copy link
Owner

niklasvh commented Jun 4, 2012

If I can undersetand you correctly, you are drawing tainted images to the canvas (http://html2canvas.hertzen.com/tests/image.jpg, it isn't in same origin as your page, unless you are running the page under http://html2canvas.hertzen.com). If you use just dog.jpg, no proxy will be used as it doesn't need one. With http://html2canvas.hertzen.com/tests/image.jpg a proxy would be used, assuming its html2canvas handling the image loading and drawing, but from the look of things you are manually attempting to draw images onto the canvas, tainting it yourself.

@chloeng
Copy link
Author

chloeng commented Jun 7, 2012

Hi Niklas, your comment made me realize that any images from different
origin drawn to the canvas will taint it and thus the screenshot won't
work. Any workaround for this besides hosting the images on the same
origin? Thank you so much for your time and reply. Really appreciate it.

On Mon, Jun 4, 2012 at 4:34 PM, Niklas von Hertzen <
reply@reply.github.com

wrote:

If I can undersetand you correctly, you are drawing tainted images to the
canvas (http://html2canvas.hertzen.com/tests/image.jpg, it isn't in same
origin as your page, unless you are running the page under
http://html2canvas.hertzen.com). If you use just dog.jpg, no proxy will
be used as it doesn't need one. With
http://html2canvas.hertzen.com/tests/image.jpg a proxy would be used,
assuming its html2canvas handling the image loading and drawing, but from
the look of things you are manually attempting to draw images onto the
canvas, tainting it yourself.


Reply to this email directly or view it on GitHub:
#103 (comment)

@niklasvh
Copy link
Owner

niklasvh commented Jun 7, 2012

Within html2canvas, the proxy is for that very purpose, to allow cross-origin images to be drawn. However, if you manually draw images, you'll need to load them manually with a proxy as well then.

@chloeng
Copy link
Author

chloeng commented Jun 7, 2012

Thanks Nicklas. Now, I get the clear picture to solve this prob ;) Thanks,
once again.

On Thu, Jun 7, 2012 at 6:22 PM, Niklas von Hertzen <
reply@reply.github.com

wrote:

Within html2canvas, the proxy is for that very purpose, to allow
cross-origin images to be drawn. However, if you manually draw images,
you'll need to load them manually with a proxy as well then.


Reply to this email directly or view it on GitHub:
#103 (comment)

@niklasvh niklasvh closed this as completed Jun 7, 2012
@andrewkolesnikov
Copy link

Same issue with any inline SVGs:

background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj...)

Good news is that if you're using SVG gradients for IE9 support, then you can simply change order of your background statements, making the svg first, then listing all native linear-gradient statements. That way, FF and Chrome will recognize them and won't throw any security errors.

@kevinchiu
Copy link

If the canvas contains both remote images and local blobs, the proxy option does not work correctly.

#823

@vishal-px
Copy link

vishal-px commented Nov 28, 2017

Hi @niklasvh
I am trying to capture web-page and send it to different domain,
Its working fine but issue is that images are not getting.

Here is my code.

jQuery(".screenshot_row_target").html2canvas({
logging: true,
useCORS : true,
//taintTest : true,
allowTaint : true,
"onrendered": function (canvas) {
  	jQuery('#screenshot_img_val').val(canvas.toDataURL("image/png"));
 	//document.getElementById("screenshot_html_form").submit();  //  redirect to edit.php
      }

});

  • In console getting this response.

     html2canvas: Preload starts: finding background-images
     html2canvas.js:19 html2canvas: Preload: Finding images
     html2canvas.js:19 html2canvas: Preload: Done.
     html2canvas.js:19 html2canvas: start: images: 1 / 1 (failed: 0)
     html2canvas.js:19 Finished loading images: # 1 (failed: 0)
     html2canvas.js:19 html2canvas: Renderer: Canvas renderer done - returning canvas obj
    

    Do you have any solution?.
    Thanks.

@shenzhuxi
Copy link

I tried to render a html with images in filesystem, and found "html2canvas: Finished loading 0 images" in the logs.
Are they considered cross-origin data, though they have the same base URL like filesystem:http://localhost:8080?

@jlahare
Copy link

jlahare commented Nov 29, 2018

is there any update over this ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

7 participants