I want to get width of an external image with javascript.
I try this code :
var image = new Image();
image.src = "1.jpg";
alert(image.width);
but it get image width in firefox and get 0 in chrome.
why it not work in chromica?
Try
image.onload = function() {alert(this.width);}
You're trying to get the width before the image has been downloaded. You have to wait, e.g.:
var image = new Image();
image.onload = function() {
alert(image.width);
};
image.src = "1.jpg";
Note that it's important to hook onload before you set src, because otherwise you have a race condition. Even though JavaScript is single-threaded on browsers (unless you use web workers), the browser is not. It can fire the load event as soon as you set src and, seeing no handlers, not queue them for callback.
Related
I suspect this question may not meet the SO criteria as it's not reproducible. If I could reproduce it I'd probably know what was causing the issue.
I am trying to add an image to the DOM via js. I set the images src in the code and then mount it. The problem that I have is that, when only setting the src and mounting it, the image doesn't load. The element is there, but it has no size, and there was no network request for the image. the onload and onerror never fire either. The img is there and the src is correct, but no image is rendered, the size is 0x0.
It's created and mounted like this:
const image = new Image();
image.src = "my-url-here";
document.querySelector("a").after(image);
I can get this working in two ways. Set the src to blank first and then what I intend it to be:
const image = new Image();
image.src = "";
image.src = "my-url-here";
document.querySelector("a").after(image);
or by preloading the image elsewhere:
// immediately:
const image = new Image();
image.src = "my-url-here";
// ...
// some other place:
const image = new Image();
image.src = "my-url-here";
document.querySelector("a").after(image);
Either works fine and are somewhat viable, though not really preferrable solutions. My question, though, is this; why is this happening? I can't reproduce it anywhere else and so it's maybe specific only to the page I'm looking at (in which case perhaps there's not much help available).
If that's not answerable, then perhaps the question is, where can I look to try and get some information on this because it's incredible difficult to know where to start with this one.
Got a image inside of a HTML document. Source is a base64 string. I want to retrieve the color of the pixel that is clicked on. Using a memory canvas all I get is zeros.
function getColor(imagecontainer,top,left){
var image = new Image();
image.onload = function() {
var canvas = document.createElement('canvas');
var context = canvas.getContext('2d');
context.drawImage(image, 0, 0);
var myData = context.getImageData(Math.round(left)-2, Math.round(top)-2, 4, 4).data;
console.log(myData, left, top);
};
image.src = imagecontainer.find("img").attr("src");
}
There are many other questions regarding the same problem, however none of the solutions could solve this problem for me. MyData always contains zeros.
Update based on new information:
The cause could simply be that the main image (imagecontainer.find("img")) isn't loaded at the time it is references.
If this image exists in DOM you can use windows.onload to run your script:
window.onload = function() {
// code that uses the image
};
as this will run only when everything has loaded incl. image data. Optionally add an inline onload handler to the image tag (not recommended), or add the src via JavaScript and monitor the onload event there.
Another possible cause is that if this is IE and the image is in the cache, onload may not trigger. You can check the image's complete property to check for this:
var image = new Image();
image.onload = onloadHandler;
image.src = imagecontainer.find("img").attr("src");
if (image.complete) onloadHandler();
function onloadHandler() {
var canvas = document.createElement('canvas');
var context = canvas.getContext('2d');
context.drawImage(image, 0, 0);
var myData = context.getImageData(Math.round(left)-2, Math.round(top)-2, 4, 4).data;
};
Although you can use this directly with the original image without loading another with the same url.
Now my entire project is too big for a copy and paste, but here is a basic breakdown of what I'm doing right now:
$(document).ready(function(){
var canvas = $('#Canvas');
var data = {source: "images\pattern.png", repeat: "repeat"} ;
var pattern = canvas.createPattern(data); //Returns 'Null' at random
});
Things I've looked at so far:
Loading time (Somewhat related, it seems to break more often when the page loads faster)
Loading order (Doesn't seem related)
Preloading the image by forcing it to an on-page image beforehand (Doesn't fix it )
Preloading it using Image() and passing the image path to Image().src (doesn't fix it either)
Passing the Image() as data.source instead of a string path (might have helped just a little)
Initting JCanvas beforehand (No function seems to exists for this)
Creating the pattern as early or as late as possible (Seems to change the frequency, but not by a lot)
It seems to have a mind of it's own and I can't figure out what I'm doing wrong. Anyone have a clue as to what I'm doing wrong?
-Edit1-
Debugging through the Jcanvas source right now and I think it has something to do with the context. Is there any way for me to preload the canvas context?
-Edit2-
Forget everything I've said about the context, I think I figured it out.
//JCanvas source
[...]
else {
// Use URL if given to get the image
img = new Image();
img.crossOrigin = params.crossOrigin;
img.src = source; //<-- source is the url of my image ("images\pattern.png")
}
// Create pattern if already loaded
if (img.complete || imgCtx) {
onload(); //<-- When this runs, the image pops up perfectly fine
} else {
img.onload = onload(); //<-- This is what causes the problem,
//onload never seems to actually run
// Fix onload() bug in IE9
img.src = img.src;
}
The img.onload event should happen directly after an image loads, but it never seems to happen.
Fact : The following code is valid.
var img = new Image();
img.onload = function() {
context.drawImage(img, 32, 32);
};
img.src = "example.png";
First Observation : The following will not draw to canvas.
var img = new Image();
img.src = "example.png";
context.drawImage(img, 32, 32);
Second Observation : The following will draw to canvas (eventually)...
var img = new Image();
img.src = "example.png";
setInterval(function() {context.drawImage(img, 32, 32);}, 1000);
Why is it that I need to call the drawImage function on a callback? And if that is the case, why does it eventually work when nested in a setInterval function?
When you set the src of the image object, the browser starts to download it. But you may or may not get that image loaded by the time the browser executes the next line of code. That's why you are drawing a "blank" image, because it ain't loaded just yet.
You need to place an onload handler to know when the image has finished loading. Only then will you draw it to the canvas:
var img = new Image(); //create image object
img.onload = function(){ //create our handler
context.drawImage(img, 32, 32); //when image finishes loading, draw it
}
img.src = "example.png"; //load 'em up!
You can only draw the image to canvas after it's loaded, that's why it works when you do it from the onload callback. And it works with setInterval because, after a certain amount of time, it eventually gets fully loaded.
I believe its because loading an image is not instant, it takes time. Once the image is loaded, then it can be drawn to the canvas
This is needed because the browser needs to "read" and eventually download the image (onload event) to correctly handle the image load. Using a setInterval to simulate this behaviour could not work, for example loading of a large image on a slow connection...
So the best way to do this is:
var img = new Image():
img.src = "image.jpeg";
img.onload = function() {
// Now you can play with your image.
}
If I use new Image() to load up an image in JavaScript, will it use a cached version if possible, or will it always load up a fresh copy?
var imgObj = new Image();
imgObj.src = 'http://...';
imgObj.onload = function (loadedImg) { }
One thing to note is that if you want onload to always happen (even when it's in cache) you should define onload before src.
var imgObj = new Image();
imgObj.onload = function (loadedImg) { }
imgObj.src = 'http://...';
It'll load from cache if it's there, the same way a <img> in your markup would.
You can force a reload by adding a bogus query string argument. If your statement assigning a URL to the src property of the image is
imgObj.src = 'http://www.mySite.com/images/anImage.png';
you could render it as
imgObj.src = 'http://www.mySite.com/images/anImage.png?foo=0';
Just understand that on subsequent loads it will still use the cached copy unless you change the query string argument.