niklasvh / html2canvas

Screenshots with JavaScript
https://html2canvas.hertzen.com/
MIT License
30.42k stars 4.79k forks source link

html2canvas does not render images located in the element #722

Closed ghost closed 7 years ago

ghost commented 8 years ago

Let's say if I would add text and a background color, then I'd press save, it would show the text and background color, but if I add an image into the div it won't show the image, but still the other things.

RomainKurtz commented 8 years ago

Hi. I have exactly the same problem.

jayantbh commented 8 years ago

Same issue here. I'm trying to get the shot of a tweet, and the attached image doesn't come through. Image attached.

stream-item-tweet-670397195221241856 2

ryanabooth commented 8 years ago

I believe images from other sites are blocked by default because it "taints the HTML5 canvas". Here is the option you need to use when you call the renderer:

attribute: allowTaint type: boolean default: false description: Whether to allow cross-origin images to taint the canvas

Found it here: https://html2canvas.hertzen.com/documentation.html.

FJBelmonte commented 7 years ago

same problem.... and my images are coming from same orign

sky1508 commented 7 years ago

I have faced the same issue, the best way to solve the issue is to run the project on the server and see the result. In my case, earlier i was running the html files directly without any server, but then after googling a bit i got a solution to try it on a server. I tried my project using Visual Studio and it was running perfectly, my images inside div tag was also being copied

SebasAlvarez commented 7 years ago

Insert de option allowTaint to view all images into your screenshot

html2canvas(document.getElementById('invoice-panel'), { letterRendering: 1, allowTaint : true, onrendered : function (canvas) { } });

biplabmalakar commented 6 years ago

I have list of div element in. When i try to capture each div by id, then some of the div half-portion captured, and some of the div's capture image blank. can you tell me what is the problem and how can i fixed it. @

qiangzi7723 commented 6 years ago

The same problem.Thanks for the solution.

manosymbian1 commented 6 years ago

html2canvas not converting imges given src in base64 format. I have printed the log. Kindly help

1283ms html2canvas: Document cloned html2canvas.js:1487 3936ms html2canvas: Initialized CanvasRenderer with size 601 x 965 html2canvas.js:1487 3937ms html2canvas: Starting NodeParser html2canvas.js:1487 4014ms html2canvas: Fetched nodes, total: 10 html2canvas.js:1487 4015ms html2canvas: Calculate overflow clips html2canvas.js:1487 4034ms html2canvas: Start fetching images html2canvas.js:1487 4044ms html2canvas: Added image #1 data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAA0JCgsKCA0LCgsODg0PEyAVExISEyccHhcgLikxMC4pL html2canvas.js:1487 4047ms html2canvas: Added image #2 data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aH html2canvas.js:1487 4051ms html2canvas: Finished searching images html2canvas.js:1487 4052ms html2canvas: Succesfully loaded image #1 ImageContainer {src: "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD…AKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigD/2Q==", image: img, tainted: null, promise: h} html2canvas.js:1487 4056ms html2canvas: Succesfully loaded image #2 ImageContainer {src: "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD…4PXOaUMB0/GlrcdiYtkcc/WkzjqfwqMPxzxRvAz3oSCx//9k=", image: img, tainted: null, promise: h} html2canvas.js:1487 4059ms html2canvas: Images loaded, starting parsing html2canvas.js:1487 4060ms html2canvas: Creating stacking contexts html2canvas.js:1487 4064ms html2canvas: Sorting stacking contexts html2canvas.js:1487 4066ms html2canvas: Render queue created with 9 items html2canvas.js:1487 4104ms html2canvas: Finished rendering html2canvas.js:1487 4109ms html2canvas: Cropping canvas at: left: 28 top: 529 width: 545 height: 0 html2canvas.js:1487 4111ms html2canvas: Resulting crop with width 545 and height 0 with x 28 and y 529

manosymbian1 commented 6 years ago

html2canvsas not rendering images given with base64 src, call is not coming back to "onrendered" function. Kindly help

1283ms html2canvas: Document cloned html2canvas.js:1487 3936ms html2canvas: Initialized CanvasRenderer with size 601 x 965 html2canvas.js:1487 3937ms html2canvas: Starting NodeParser html2canvas.js:1487 4014ms html2canvas: Fetched nodes, total: 10 html2canvas.js:1487 4015ms html2canvas: Calculate overflow clips html2canvas.js:1487 4034ms html2canvas: Start fetching images html2canvas.js:1487 4044ms html2canvas: Added image #1 data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAA0JCgsKCA0LCgsODg0PEyAVExISEyccHhcgLikxMC4pL html2canvas.js:1487 4047ms html2canvas: Added image #2 data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aH html2canvas.js:1487 4051ms html2canvas: Finished searching images html2canvas.js:1487 4052ms html2canvas: Succesfully loaded image #1 ImageContainer {src: "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD…AKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigD/2Q==", image: img, tainted: null, promise: h} html2canvas.js:1487 4056ms html2canvas: Succesfully loaded image #2 ImageContainer {src: "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD…4PXOaUMB0/GlrcdiYtkcc/WkzjqfwqMPxzxRvAz3oSCx//9k=", image: img, tainted: null, promise: h} html2canvas.js:1487 4059ms html2canvas: Images loaded, starting parsing html2canvas.js:1487 4060ms html2canvas: Creating stacking contexts html2canvas.js:1487 4064ms html2canvas: Sorting stacking contexts html2canvas.js:1487 4066ms html2canvas: Render queue created with 9 items html2canvas.js:1487 4104ms html2canvas: Finished rendering html2canvas.js:1487 4109ms html2canvas: Cropping canvas at: left: 28 top: 529 width: 545 height: 0 html2canvas.js:1487 4111ms html2canvas: Resulting crop with width 545 and height 0 with x 28 and y 529

sandeepnagra commented 6 years ago

@SebasAlvarez - the allowTaint option doesn't work anymore. Does it still work for you?

venkateshduddu commented 6 years ago

@SebasAlvarez , @sandeepnagra : am using this code for image screenshot in new tab but image not rendering and also i tired with "allowTaint:true" it's working only in inside same window but not in new tab. this is my code: function render(){ html2canvas(document.body, { allowTaint : true, onrendered: function(canvas) { document.body.appendChild(canvas); window.open(canvas.toDataURL()); } }); } can you tell me what is the problem, how can you fix this one??

sandeepnagra commented 6 years ago

@venkateshduddu - are you shifting the focus to new tab first before taking screenshot?

venkateshduddu commented 6 years ago

@sandeepnagra - no sandeep, am just using click event. one more thing screenshot working if i use local image path but server path not working in new tab.

sandeepnagra commented 6 years ago

@venkateshduddu - a click event won't shift the focus to new tab automatically, you have to trigger that. So try that first, I am 100% sure it will solve your issue.

Regarding the server path, is that network drive authenticated? If yes, are you authenticating before uploading files to the network drive? It's a whole different story if you want to upload them to S3 bucket.

AntonioDilorenzo commented 6 years ago

hi when i try to screen an iframe with internal ip camera, it return a void image, please can you help me?

youmakr commented 5 years ago

If I used allowTaint then download option not worked . Please help

Sotyoyo commented 5 years ago

same problem.... and my images are coming from same orign

I just fixed this problem. pls enable the option 'useCORS' to 'true' codes bellow: html2canvas( document.querySelector(".preview_area"), { logging: true, letterRendering: 1, // allowTaint: false useCORS: true } ).then(canvas => { })

sivagopi5072 commented 5 years ago

Thank you very much @Sotyoyo , My bug was fixed with the above code. THank you Thank you

kasim444 commented 5 years ago

@Sotyoyo Thanks a lot bro, god bless you <3

CodingApp commented 5 years ago

@Sotyoyo Thank you so much, its work for me :)

M-Yasir-Hussain commented 5 years ago

Image is not render is there any problem in my code ?

html2canvas(document.getElementById("html-2-pdfwrapper"), { logging: true, letterRendering: 1, allowTaint: false, useCORS: true, onrendered: function(canvas) { var img = canvas.toDataURL('image/png'); var doc = new jsPDF(); doc.addImage(img, 'JPEG', 20, 20); doc.save('test2.pdf'); } });

yurimagagnatto commented 5 years ago

same problem.... and my images are coming from same orign

I just fixed this problem. pls enable the option 'useCORS' to 'true' codes bellow: html2canvas( document.querySelector(".preview_area"), { logging: true, letterRendering: 1, // allowTaint: false useCORS: true } ).then(canvas => { })

its work! thx!

yurimagagnatto commented 5 years ago

same problem.... and my images are coming from same orign

I just fixed this problem. pls enable the option 'useCORS' to 'true' codes bellow: html2canvas( document.querySelector(".preview_area"), { logging: true, letterRendering: 1, // allowTaint: false useCORS: true } ).then(canvas => { })

that's is right \/

html2canvas(document.querySelector("#id-of-element"),{ logging: true, letterRendering: 1, allowTaint: false, useCORS: true }).then(canvas => { var imgData = canvas.toDataURL('image/jpeg'); });

trungegd commented 5 years ago

Insert de option allowTaint to view all images into your screenshot

html2canvas(document.getElementById('invoice-panel'), { letterRendering: 1, allowTaint : true, onrendered : function (canvas) { } });

Thanks. It works fine.

But I can't clone image style to canvas

Swathi178 commented 4 years ago

I still face the same issue even after using above options below is my code. var element = document.querySelector("#map-image-id"); html2canvas(element, { logging: true, letterRendering: 1, allowTaint: false, useCORS: true }).then(canvasElm => { var imageType = "image/png"; var imageData = canvasElm.toDataURL(imageType); var src = encodeURI(imageData); console.log("src", src); console.log("image Data", imageData);

zeroone001 commented 4 years ago

I still face the same issue even after using above options below is my code. var element = document.querySelector("#map-image-id"); html2canvas(element, { logging: true, letterRendering: 1, allowTaint: false, useCORS: true }).then(canvasElm => { var imageType = "image/png"; var imageData = canvasElm.toDataURL(imageType); var src = encodeURI(imageData); console.log("src", src); console.log("image Data", imageData);

same to you. Have you solved it?

aymanElkhouly-sharingGroup commented 4 years ago

I still face the same issue even after using above options below is my code. var element = document.querySelector("#map-image-id"); html2canvas(element, { logging: true, letterRendering: 1, allowTaint: false, useCORS: true }).then(canvasElm => { var imageType = "image/png"; var imageData = canvasElm.toDataURL(imageType); var src = encodeURI(imageData); console.log("src", src); console.log("image Data", imageData);

same issue with me any help

kkozler commented 4 years ago

I'm seeing the same issue. What am I doing wrong?

html2canvas(document.getElementById(<id>), {
    logging: true,
    letterRendering: 1,
    allowTaint: false,
    useCORS: true
}).then(result => {
    var img = result.toDataURL("image/png");
    savePng(img);
});
SylarRuby commented 4 years ago

The below also works if you want to include <img src-"..." />:

html2canvas(report, {letterRendering: 1, allowTaint: true, useCORS: true})
            .then((canvas) => {      
                const imgData = canvas.toDataURL('image/png');
               // const pdf = new jsPDF();
               // pdf.addImage(imgData, 'PNG', 10, 10);
                //pdf.save("foo.pdf");  
            });
venkateshCorezi commented 4 years ago

My content is contains image that come from Aws.s3(). The above mentioned Comments are not working for my case.

html2canvas(content, {letterRendering: 1,allowTaint: false,useCORS:true }) .then(canvas => { const imgData = canvas.toDataURL('image/png'); console.log(imgData); const pdf = new jsPDF(); pdf.addImage(imgData, 'PNG', 10, 10, canvas.width, canvas.height); pdf.save('download.pdf'); });

The output canvas only contains a blank box instead of image. Any one have a solution for my case?

alvnrapada commented 4 years ago

My content is contains image that come from Aws.s3(). The above mentioned Comments are not working for my case.

html2canvas(content, {letterRendering: 1,allowTaint: false,useCORS:true }) .then(canvas => { const imgData = canvas.toDataURL('image/png'); console.log(imgData); const pdf = new jsPDF(); pdf.addImage(imgData, 'PNG', 10, 10, canvas.width, canvas.height); pdf.save('download.pdf'); });

The output canvas only contains a blank box instead of image. Any one have a solution for my case?

same issue here. images coming from S3 bucket

saadh393 commented 4 years ago

same problem.... and my images are coming from same orign

I just fixed this problem. pls enable the option 'useCORS' to 'true' codes bellow: html2canvas( document.querySelector(".preview_area"), { logging: true, letterRendering: 1, // allowTaint: false useCORS: true } ).then(canvas => { })

Thanks It works for me ❤❤

Vishal-Kank commented 4 years ago

Access to image at 'https://image/logo link' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Is this the reason why my logo is not appearing in the pdf file. Rest all the text with css applied and the brand logo which is in my static folder is comming. Please do answer need help on this Iam trying this from more than 2 weeks.

khaiquangnguyen commented 4 years ago

For anyone coming here, after trying many things, I found out that for getting images from an external resources ( such as S3 bucket), you have to enable both useCORS = true for html2canvas, and enable CORS policy on the images served from S3.

zeusstl commented 3 years ago

I resolved it using the html2canvas proxy. You can see some details on usage and testing here: https://github.com/zeusstl/html2canvas-proxy-nodejs

thetnaingtn commented 3 years ago

I also had that kind of issue. But now I think I have a solution. Before adding an image to canvas add crossOrigin = 'Anonymous' to the image.Like that: let img = new Image(); img.src = url; img.crossOrigin = 'Anonymous';

I hope that will also work for you!

hanifkumara commented 3 years ago

@Sotyoyo Alhamdulillah, thank you broo

SalahAdDin commented 2 years ago

It does not work with early versions.

shashwa7-dev commented 2 years ago

This is react project where I have created a card that has some details and hero image! On download it downloads the card with the image! Here is the sandbox file you guys can look into:https://codesandbox.io/s/html2canvas-demo-7cfd2u?file=/src/App.js

vladern commented 2 years ago

This is react project where I have created a card that has some details and hero image! On download it downloads the card with the image! Here is the sandbox file you guys can look into:https://codesandbox.io/s/html2canvas-demo-7cfd2u?file=/src/App.js

Glory to Heroes

policiadestiny commented 2 years ago

useCORS: true

ogheneovo12 commented 2 years ago

html2canvas doesn't evaluate srcset rules and uses only the src values, it also ignores the object-fit style of images

SalahAdDin commented 2 years ago

html2canvas doesn't evaluate srcset rules and uses only the src values, it also ignores the object-fit style of images

why?

ogheneovo12 commented 2 years ago

html2canvas doesn't evaluate srcset rules and uses only the src values, it also ignores the object-fit style of images

why?

Went through the doc and saw that object-fit wasn’t supported, had to switch to media queries instead of the using srcsets rules as there’s no specification that states if html2canvas considers that when processing images.

Diegoafv commented 1 year ago

Still getting the same issue.

rrfaria commented 1 year ago

I found out what is happen even using useCORS. I used 2 different images to see how it performs. One with cors allwoing cors anonymously and other without permission

// img 1- with cors blocked but rendering on html and not downloading using html2canvas
<img
 src="https://a-static.mlcdn.com.br/618x463/kit-gamer-razer-battle-bundle-mouse-deathadder-v2-headset-gamer-blackshark-v2-x-mousepad-gigant/formatameupc/kitrz/a78905f66dd2f260c5daa60dd726c80a.jpeg"
 >

 //  img 2- with cors allowed and download using html2canvas
 <img
 src="https://lh3.googleusercontent.com/acezh821GREUTqwpxvzCnLtRfEkmkLF1aHSj3d8RYRFMvdCA0KL-9IN7XvJnke2agLv3pq-dpU2ceTehC3MFB22EnOgps0UbLVU0ujg=w600"
 crossorigin="anonymous"
 >
 html2canvas(div, {
  letterRendering: 1,
  logging: true,
  letterRendering: 1,
  useCORS: true,
}).then(function(canvas) {
  var myImage = canvas.toDataURL();
  downloadURI(myImage, "promo.png");
});
function downloadURI(uri, name) {
  var link = document.createElement("a");

  link.download = name;
  link.href = uri;
  document.body.appendChild(link);
  link.click();
  //after creating link you should delete dynamic link
}

the problem is: img 1 has no cors enabled on server but it still rendering on html. I can see it on my rendered html but when I click to start html2canavas it doesn't exports the image. if I set crossorigin="anonymous" then I can't see on html rendered and also can't download.

Now if I use img 2 with crossorigin="anonymous" it's renders on html and also download.

And the error I think everyone is having is because we don't have control of the server to allow cors, but we still see html rendered with the image and since it's rendered we believe it can be downloaded.

I shared this to see if someone have any insight how to solve it

Bawanthathilan commented 1 year ago

Still getting the same issue.

me too

DaveCole commented 1 year ago

I spent hours on this issue and discovered this article which explained what could be happening.

Essentially, Chromium caches images once loaded, but does not preserve the Access-Control-Allow-Origin header. So when you throw it at html2canvas it fails with a CORS error and doesn't render. The idea of adding a random query string after the URL works to a degree, but html2canvas uses the exact same URL when it does its rendering as what you used on the HTML page and it fails. I suggest in a future version they add a random query string argument after the URL or append one to the existing query string to prevent this.

In the meantime, the only workaround I could find was the load the image server-side, base64-encode it into a string, pass that over to the client and then render that in an image tag.

If you're using node, the server side code would look something like this:

import fetch from 'node-fetch'
const response  = await fetch(url);
image_base64 = (await response.buffer()).toString('base64');

and the image tag would look something like:

<img src=`data:image/jpeg;base64, ${image_base64}` />

Your mimetype may vary, I would write a function that parsed the file extension and determined it from there.

catalinberta commented 1 year ago

If possible, I recommend giving html-to-image a try also, instead of html2canvas. For me it fixed 2 main issues: