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

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

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

Comments

Projects
None yet
7 participants
@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

This comment has been minimized.

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

This comment has been minimized.

Copy link

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

This comment has been minimized.

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

This comment has been minimized.

Copy link

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

This comment has been minimized.

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

This comment has been minimized.

Copy link

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 Jun 7, 2012

@andrewkolesnikov

This comment has been minimized.

Copy link

andrewkolesnikov commented Aug 13, 2012

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

This comment has been minimized.

Copy link

kevinchiu commented Mar 11, 2016

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

#823

@vishal-px

This comment has been minimized.

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

This comment has been minimized.

Copy link

shenzhuxi commented Mar 5, 2018

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

This comment has been minimized.

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