I am trying to get the dimensions of an image in order to resize (or size) a canvas of it's length with twice the width. (So, for a 400x800 image I want a 800x800 canvas). What I'm trying to do right now is load the image twice, once to determine it's size and another time to display it. My HTML w/ Javascript/JQuery looks like
<!DOCTYPE html>
<html>
<head>
<title>Canvas from scratch</title>
<meta charset="utf-8">
<script
src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script src="jcanvas.min.js"></script>
</head>
<body>
<canvas id="myCanvas" width="1100" height="500">
</canvas>
<script>
$("<img />").attr("src", "test1image.jpg").load(function() {
/* This is where I'd like to load the image to get its dimensions */
});
$(document).ready(
function() {
var imgWidth, imgHeight;
var imageData;
var image = new Image();
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
$(image).load(function() {
/* This is where the image is loaded and
inserted into the canvas */
ctx.drawImage(image, 0, 0);
});
image.src = "test1image.jpg";
imageData = ctx.getImageData(0, 0,
image.width,
);
/* This is just part of the image manipulation,
bland right now */
var newImgData = ctx.createImageData(imageData.width,
imageData.height);
for ( var i = 0; i < newImgData.data.length; i += 4) {
newImgData.data[i + 0] = 255;
newImgData.data[i + 1] = 0;
newImgData.data[i + 2] = 0;
newImgData.data[i + 3] = 255;
}
ctx.putImageData(newImgData, imageData.width, 0);
});
</script>
</body>
</html>
One thing I've kept trying but noticed is not working is trying to place the function before (document).ready, but if the (document).ready call always comes first. I can't seem to get the image to load without the canvas already being created (because it is in the (document).ready call). Can anyone explain what's going on?
Thanks.
Edit_1: I just tried adding
jQuery(window).load(function() {
$("<img />").attr("src", "test1image.jpg").load(function() {
imgWidth = this.width;
});
});
to the top of the script, but imgWidth is being declared as undefined in (document).ready.
Edit_2: So, that actually worked really well blgt. Here's the new code, and it's 100% functional. The new canvas size is exactly what I wanted, based on the image dimensions and it all works... only thing I'm thinking is that there might be one too many nested functions but I'll try to work that out on my own.
<!DOCTYPE html>
<html>
<head>
<title>Canvas from scratch</title>
<meta charset="utf-8">
<script
src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script src="jcanvas.min.js"></script>
</head>
<body>
<canvas id="myCanvas" width="1100" height="500">
</canvas>
<script>
$(document).ready(
function() {
$("<img>").attr("src", "test1image.jpg").on('load', function() {
var imgWidth, imgHeight;
var imageData;
var image = new Image();
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
ctx.canvas.width = this.width * 2;
ctx.canvas.height = this.height;
$(image).on("load", function() {
/* This is where the image is loaded and
inserted into the canvas */
ctx.drawImage(image, 0, 0);
});
image.src = "test1image.jpg";
imageData = ctx.getImageData(0, 0,
this.width,
this.height);
/* This is just part of the image manipulation,
bland right now */
var newImgData = ctx.createImageData(imageData.width,
imageData.height);
for ( var i = 0; i < newImgData.data.length; i += 4) {
newImgData.data[i + 0] = 255;
newImgData.data[i + 1] = 0;
newImgData.data[i + 2] = 0;
newImgData.data[i + 3] = 255;
}
ctx.putImageData(newImgData, imageData.width, 0);
});
});
</script>
</body>
</html>
This syntax: .load()
is deprecated, use .on('load'...
instead. Also, this won't delay execution of the function in .ready
. Is there a reason you can't do the simple, stupid thing and just put a callback to that function inside the .on('load', handler)
handler instead?
$(document).ready(function() {
$("<img>").attr("src", "test1image.jpg").on('load', function() {
// do stuff with dimensions
var imgWidth, imgHeight;
var imageData;
// ... etc.
});
});
You're trying to shoehorn a synchronous sequence onto an asynchronous model, and basically you just don't want to do this.
The document ready event is supposed to fire before other assets have been loaded: http://api.jquery.com/ready/ - note it mentions exactly the case you're asking about.
In cases where code relies on loaded assets (for example, if the dimensions of an image are required), the code should be placed in a handler for the load event instead.
So you should be able to just change your code to use document.load()
instead of document.ready()
but this will then wait until all assets are loaded. If you only want to wait for that specific image to load, you should move the code from document.ready
to the image's load
event.
EDIT:
Your new code basically does the last option - moves the code into the image's load event, which is probably the best overall as it allows your code to run as soon as the particular image is ready. You can potentially make it happen sooner by pre-loading the image in an inline script before loading your JS libraries etc. which would allow the image to start downloading in parallel to other assets, rather than waiting for the document ready event to start the image loading.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.