I can't seem to have Chrome browser show the true image size via <img>
and also by drawImage via canvas context. Explorer shows both of these
correctly.
In Chrome, the image shown is not by the dimensions of the original image
but a scaled down one. The browser when rendered from a Web server seems to
have something to do with it. Curiously enough, when open the browser on
the html file locally:
E.g. file:///C:/xampp/htdocs/Website_TEST_active/test1.html, the image dimensions are correct.
Attached is a stripped down HTML and Javascript code. Appreciate any insights.
Thanks
Sean
<!DOCTYPE html>
<html>
<body>
<p>Image to use:</p>
<img id="scream" onload="loadImage()" src="pics/cover.jpg" alt="Test">
<p>Canvas:</p>
<canvas id="myCanvas" width="854" height="480" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.
</canvas>
<script>
window.onload = function() {
// Not used
}
/*
* Upon image load, draw image on canvas
*/
function loadImage(){
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
var img = document.getElementById("scream");
ctx.drawImage(img, 0,0, img.naturalWidth, img.naturalHeight);
console.log("Original Image W=" + img.naturalWidth +
" H=" + img.naturalHeight);
}
</script>
</body>
</html>
I found something that might be right for what you're asking.
Here's the link- https://superuser.com/a/364875
Open Developer tools (Ctrl+Shift+I or use the Settings Icon at the
top-right of your browser window => Tools => Developer tools) and on
the relevant page, switch to the Network tab and reload the page.
In the Size column you'll see the size of everything loaded
(Documents, Stylesheets, Images, Scripts, ...). You can enable a
filter to help you find out what you need - at the bottom-center of
Developer tools frame.
Related
Hi I have the following problem.
I'm generating a SVG image (https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Drawing_DOM_objects_into_a_canvas).
The image is generated correctly and looks ok.
Now I need to get the data URI, but everytime I try to get that from canvas.toDataURL() this message appears Uncaught DOMException: Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported.(…)
I've created some sample code to illustrate the situation.
</!DOCTYPE html>
<html>
<head>
<title>SVG to PNG</title>
</head>
<body>
<canvas id="canvas" style="border:2px solid black;" width="200" height="200">
</canvas>
<script type="text/javascript">
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var data = '<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200">' +
'<foreignObject width="100%" height="100%">' +
'<div xmlns="http://www.w3.org/1999/xhtml" style="font-size:40px">' +
'<em>I</em> like ' +
'<span style="color:white; text-shadow:0 0 2px blue;">' +
'beer</span>' +
'</div>' +
'</foreignObject>' +
'</svg>';
var domURL = window.URL || window.webkitURL || window;
var img = new Image();
var svg = new Blob([data], {type: 'image/svg+xml'});
var url = domURL.createObjectURL(svg);
img.onload = function () {
ctx.drawImage(img, 0, 0);
domURL.revokeObjectURL(url);
var dataURL = canvas.toDataURL();
console.log(dataURL);
};
img.src = url;
</script>
</body>
</html>
This code generates the following image
This is correct, but then when these lines are executed
var dataURL = canvas.toDataURL();
console.log(dataURL);
It throws the error. I'm doing this inside the image onload method to allow the image finish drawing to the canvas. If I try to get the dataURL from outside the onload method, the canvas hasn't finished loading, so it would give me an empty image.
I've been searching a lot but I couldn't find the answer yet. This is something related to CORS. I've installed the chrome plugin CORS and added the img, the thing is that this is just an example, and a CORS based solution would not be useful, because I'm working on an application that's running over a crippled chromium browser (I mean the browser just shows the web app, you can't do anything there except interact with the app).
To notice you can obtain the data URI, with
inspect --> network --> select the image and open in sources panel and there it is just copy image as data uri.
I get the base64 image that way, and if I use some decoder like this (http://base64online.org/decode/) it's showing the image correctly.
So definitely the problem is that I'm getting the data URI before the canvas is drawn.
Any ideas?
Thanks in advance!
Regards
Mauro
This has nothing to do with CORS. You are not doing any request to an external resource.
The issue is that drawing an svg (moreover when it contains html elements) is a really sensitive action for browsers.
That's why there are a lot of limitations on this technique (you can't load external resources, scripts are ignored, you can't style the content from external CSS, all default browser and OS styles are disabled to avoid fingerprinting etc.).
I don't work for safari nor chrome, so I can't tell for sure, but I think they aren't able to provide enough security on one of these points (safari realised it in v9, and it's a known issue in chrome too).
So what they do, is that they taint the canvas, locking any of its export methods. (Note that IE < Edge did also taint the canvas whenever any svg had been drawn to the canvas for similar security reasons).
If what you want is to rasterize DOM elements, then you should parse the DOM and all its applied styles, and reproduce it with canvas drawings methods.
Doing so, you can bypass most security issues, and no UA will taint the canvas. Some library out there do exactly this, the most famous being html2canvas.
If what you want is to draw this image, then you can rewrite it without using a foreignObject (svg text has more options than canvas one), then use a library like canvg to render it on your canvas (because otherwise IE will taint the canvas as said previously).
Note : chrome's issue can be workedaround, but I'm not sure it's a good idea, it will still not work in Safari, nor in IE < Edge, and chrome may just have forgotten to block it too and will in next releases, anyway, here is how :
var canvas = document.getElementById('c');
var ctx = canvas.getContext('2d');
var data = '<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200">' +
'<foreignObject width="100%" height="100%">' +
'<div xmlns="http://www.w3.org/1999/xhtml" style="font-size:40px">' +
'<em>I</em> like ' +
'<span style="color:white; text-shadow:0 0 2px blue;">' +
'beer</span>' +
'</div>' +
'</foreignObject>' +
'</svg>';
var img = new Image();
// instead of a blobURL, if we use a dataURL, chrome seems happy...
var url = 'data:image/svg+xml; charset=utf8, ' + encodeURIComponent(data);
img.onload = function() {
c.width = this.width;
c.height = this.height;
ctx.drawImage(img, 0, 0);
var dataURL = canvas.toDataURL();
console.log(dataURL);
};
img.src = url;
<canvas id="c"></canvas>
I have a weather webpage with a webcam image that uploads every 2 minutes.
I want to change the webpage.
I want the webcam image to be the background on the webpage, but I want that image to update itself once a minute.
The reason I want it to be the background image is so I can put weather report stickers on top of it (in the foreground) in the bottom corners or at the bottom of the page centered.
Right now the webcam takes the picture and uploads it to my domain host. Then I download it to my webpage. It's fairly kluged together at this point but it works. You can see it here
Any help appreciated
Greg
You can do something like this and make the canvas a background. But this snippet will not work in here. As they deprecated the feature in insecure origins for security reasons perhaps.
getUserMedia() no longer works on insecure origins. To use this feature, you should consider switching your application to a secure origin, such as HTTPS. See this for more details.
var video = document.getElementById("live");
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext('2d');
function start() {
navigator.webkitGetUserMedia({
video: true
}, gotStream, function() {});
}
function gotStream(stream) {
video.src = webkitURL.createObjectURL(stream);
}
function refresh() {
ctx.drawImage(video, 0, 0, 500, 375);
ctx.stroke();
setTimeout(function(){
refresh;
}, 60000)
}
refresh();
start();
<video style="display:none;" id="live" width="500" height="375" autoplay style="border:5px solid #000000"></video>
<canvas id="myCanvas" width="500" height="375" style="border:5px solid #000000"></canvas>
I am using sketch.js http://intridea.github.io/sketch.js/ so users can create drawing in my app. Once they are finished drawing, and click save, I convert the drawing into a png image using this function:
convertCanvasToImage = (canvas) ->
image = new Image()
image.src = canvas.toDataURL("image/png")
image
And then I just append the image to the DOM.
But what if a user wants to edit the drawing afterwards? How can I take that image and add it to the canvas that sketch.js uses?
I tried the following with failed results. When you click the png image I run this code to try to append the image to canvas, but it does not seem to work at all. The canvas is in a modal and once it appears I run the following code to append the image to canvas, but no image appears.
template.$('#sketchModal').on 'shown.bs.modal', (e) ->
c = document.getElementById("sketchPad")
ctx = c.getContext("2d")
ctx.drawImage(e.target, 0, 0)
I haven't used sketch js before, but seeing this code I came with an idea
<div class="tools">
Marker
Eraser
</div>
<canvas id="tools_sketch" width="800" height="300" style="background: url(http://farm1.static.flickr.com/91/239595759_3c3626b24a_b.jpg) no-repeat center center;"></canvas>
<script type="text/javascript">
$(function() {
$('#tools_sketch').sketch({defaultColor: "#ff0"});
});
</script>
You don't want to append the image in canvas but rather add it as a background.
Try it and please inform me if it worked.
I'm just trying to figure out how to get an image to draw on a canvas. I followed a tutorial on W3 schools, but when i tried it on my own it doesn't seem to be working. I copy and paste the code below into an HTML file, and the image never loads into the canvas. I downloaded the picture into the same directory. I've been asking around, and looked online, but no one seems to know what the problem is.
I'm using an updated version of chrome (Version 29.0.1547.76 m).
<!DOCTYPE html>
<html>
<body>
<p>Image to use:</p>
<img id="scream" src="img_the_scream.jpg" alt="The Scream" width="220" height="277">
<p>Canvas:</p>
<canvas id="myCanvas" width="250" height="300" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.</canvas>
<script>
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
var img=document.getElementById("scream");
this.ctx.drawImage(img,10,10);
</script>
</body>
</html>
Your image probably hasn't finished loading at the point you are using drawImage:
HTML
Add onload handler in img tag:
<img id="scream" onload="draw()" src="...
Then the function to handle it:
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
var img=document.getElementById("scream");
function draw() {
ctx.drawImage(img,10,10);
}
Online demo here
Be aware of that where you place the scripts in your document matters as well.
I would recommend you setting the src attribute in JavaScript as well. That makes it more "safe" to handle the onload (or subscribed event with img.addEventListener('load', ...).
you should use the following approach that first let the image loaded then display:
image.onload = function() {
pic.getContext('2d').drawImage('your image to display', 0,0);
}
"If you try to call drawImage() before the image has finished loading, it won't do anything (or, in older browsers, may even throw an exception). So you need to be sure to use the load event so you don't try this before the image has loaded."
example:
var img = new Image(); // Create new img element
img.addEventListener('load', function() {
// execute drawImage statements here
}, false);
img.src = 'myImage.png'; // Set source path
Source
I want to use CSS to style an element on a webpage and then to use that element as a static png. Is it possible to draw html node on eg. canvas and save such image with transparency to a file?
I want to find a way to take already existing HTML with CSS and render it to PNG file keeping transparency.
Saving HTML elements to images requires a Complicated Answer!
First, for very good security reasons, browsers do not to allow same-page imaging of HTML elements. Imagine for example a malicious script that takes the HTML input form containing your banking username+password and converts it to an image and sends the image to a thief—not good!
Therefore, IE simply block same page HTML element imaging--period.
Chrome and Firefox might still have a feature (bug?!) that allows you to turn HTML elements into images like this:
1. Embed the HTML element into an SVG element using "foreignObject".
2. Draw the SVG element into a Canvas element.
3. Use canvas.toDataURL(‘image/png’) to get an encoded string representing the png image.
Since it looks like you are in control of styling the HTML, you might have a full solution by using a “headless” HTML generator like PhantomJs.org (phantomjs.org). You can use Phantomjs to generate and style the HTML element. PhantomJs then has a rasterizer you can use to convert that element into an image. Plus, If you can serve up a web page that contains only the styled HTML you need, then this 1 line of PhantomJs code will get you a png of that page:
phantomjs rasterize.js http://myHtmlOnMyPage.html myHtmlImage.png
The Chrome/Firefox code is found here: https://developer.mozilla.org/en-US/docs/HTML/Canvas/Drawing_DOM_objects_into_a_canvas
And looks like this:
<!DOCTYPE html>
<html>
<body>
<p><canvas id="canvas" style="border:2px solid black;" width="200" height="200"></canvas>
<script>
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var data = "<svg xmlns='http://www.w3.org/2000/svg' width='200' height='200'>" +
"<foreignObject width='100%' height='100%'>" +
"<div xmlns='http://www.w3.org/1999/xhtml' style='font-size:40px'>" +
"<em>I</em> like <span style='color:white; text-shadow:0 0 2px blue;'>cheese</span>" +
"</div>" +
"</foreignObject>" +
"</svg>";
var DOMURL = self.URL || self.webkitURL || self;
var img = new Image();
var svg = new Blob([data], {type: "image/svg+xml;charset=utf-8"});
var url = DOMURL.createObjectURL(svg);
img.onload = function() {
ctx.drawImage(img, 0, 0);
DOMURL.revokeObjectURL(url);
};
img.src = url;
</script>
</body>
</html>
Just found an easy way via Safari.
Right click on element, Inspect Element, then in the Inspector right click on the element node you want to export and pick Capture Screenshot. This to me resolves transparency. Safari Version 13.1 (14609.1.20.111.8)
Yes it is possible to save a HTML element as image (PNG file). See
Capture HTML Canvas as gif/jpg/png/pdf?
how to save canvas as png image?
HTML5 Save canvas to PNG
Drawing PNG to a canvas element -- not showing transparency
http://asserttrue.blogspot.de/2011/12/in-yesterdays-post-i-showed-how-to.html