I'm trying to get the width of an image after a change in the height and I only have the URL (the image is not in a tag in the HTML) so I tried this code:
var img = document.createElement("img");
img.src = "./images/niceImages.jpg";
img.style.height = "200px";
console.log(img.clientWidth);
But the property "clientWidth" returned 0. I know that maybe with JQuery it is a lot easier however, I want do it with pure Javascript.
Does anyone know if this can be done? Or at least how to get the aspect ratio or width and height of the image URL?
If you append the image you create to the DOM then you should find that the width is then calculated and is then available as normal
var img = document.createElement("img");
img.src = "http://cdn.sstatic.net/stackexchange/img/logos/so/so-icon.png";
img.onload = function(){
img.style.height = "200px";
img.style.visibility = 'hidden';
document.body.appendChild(img);
console.log(img.clientWidth);
}
I figured out some better solutions -
Javascript
function loadImage() {
const imgSrc = 'https://cdn.pixabay.com/photo/2015/03/26/09/47/sky-690293_1280.jpg'
const img = new Image();
img.src = imgSrc;
img.onload = function() {
document.body.appendChild(img); // You can get the image ratio without inserting the image in body
alert('Image ratio' + img.width/img.height);
}
}
<button onClick="loadImage()">Load Image</button>
Angular (Typescript) - ( Snippet will not run because of angular unavailability )
public getImageRatio(url: string): Promise <any> {
return Promise((resolve, reject) => {
const img = new Image();
img.src = url;
img.onload = function() {
resolve(img.width / img.height);
};
img.onerror = function() {
reject('Image failed to load');
};
});
}
async loadImage(url) {
const imageRatio = await getImageRatio('image-url-here');
alert(imageRatio);
}
loadImage(url);
Related
Ho do I use getBoundingClientRect() to determine the width and height of image
function popUp() {
var img = document.createElement('img');
img.id = "TT";
img.src = "https://picsum.photos/200/300";
document.body.appendChild(img);
var img = document.getElementById("TT");
console.log(img)
var dims = img.getBoundingClientRect();
console.log(dims)
}
popUp();
This is because the image is not loaded at the time of log. You need to console.log inside onload function
function popUp() {
var img = document.createElement('img');
img.id="TT";
img.src="https://picsum.photos/200/300";
document.body.appendChild(img);
img.onload = function(){
var img = document.getElementById("TT");
var dims = img.getBoundingClientRect();
console.log(dims)
}
}
popUp();
If you want the function to await for further execution of the function until the image is loaded you can create a promise and then await for it. But this will make the structure of the code asynchronous
async function popUp() {
var img = document.createElement('img');
img.id="TT";
img.src="https://picsum.photos/200/300";
document.body.appendChild(img);
const imageLoaded = new Promise((res, rej) => {
img.onload = function(){
var img = document.getElementById("TT");
var dims = img.getBoundingClientRect();
res(dims)
}
});
const data = await imageLoaded;
console.log(data)
}
popUp();
I want to preload my images but don't necessarily want to append them to the DOM. If I preload an image will it effectively be precached?
My understanding is that caching works by reference to the src of an image. From playing around it seems as if preloading in order to precache does indeed work. However, I'm not sure; this may be unreliable or have some negative effect on performance.
I'm using the image constructor to preload.
const img = new Image();
img.src = imageArray[i].url;
Yes, it does indeed work.
function preloadImage(url){
const img = new Image();
img.src = imageArray[i].url;
}
However, there is a couple of approach. For example, delaying preloading until after the page loads:
function preloader() {
if (document.images) {
var img1 = new Image();
var img2 = new Image();
var img3 = new Image();
img1.src = "http://url/image-001.jpg";
img2.src = "http://url/image-002.jpg";
img3.src = "http://url/image-003.jpg";
}
}
function addLoadEvent(func) {
var oldonload = window.onload;
if (typeof window.onload != 'function') {
window.onload = func;
} else {
window.onload = function() {
if (oldonload) {
oldonload();
}
func();
}
}
}
addLoadEvent(preloader);
I don't need an image inside the DOM, but need to get it's dimensions.
Trying to create a temporary img element this way:
let src = 'images/01.jpg';
let img = document.createElement('img');
img.src = src;
let w = img.naturalWidth;
let h = img.naturalHeight;
console.log(w); // 0
console.log(h); // 0
$(img).remove();
Result is 0 and 0. The real dimensions are 1349 and 250.
How can I get them, without disturbing existing page layout?
You have to wait for the image to be loaded:
let src = 'http://www.fillmurray.com/g/200/300';
let img = document.createElement('img');
img.onload = () => {
console.log(img.naturalWidth);
console.log(img.naturalHeight);
}
img.src = src;
Until loaded, there's no way for the browser to know the dimensions of your image. If you need the dimensions in another function, you either have to use a callback parameter or return a Promise:
let src = 'http://www.fillmurray.com/g/200/300';
// with a callback
const loadImgCallback = (url, callbackFn) => {
let img = document.createElement('img');
img.onload = () => { callbackFn(img); }
img.src = src;
}
// with Promise
const loadImgPromise = url => new Promise((ok, fail) => {
let img = document.createElement('img');
img.onload = () => { ok(img); }
img.onerror = fail;
img.src = url;
});
/* === USAGE EXAMPLES === */
loadImgCallback(src, img => {
console.log(`callback, naturalWidth: ${img.naturalWidth}`);
console.log(`callback, naturalHeight: ${img.naturalHeight}`)
});
loadImgPromise(src).then(img => {
console.log(`Promise, naturalWidth: ${img.naturalWidth}`);
console.log(`Promise, naturalHeight: ${img.naturalHeight}`)
});
It's up to you to decide which solution you prefer.
Just assign it to the image object and for image to load :)
let src = 'https://images.pexels.com/photos/428338/pexels-photo-428338.jpeg';
var img = new Image();
//img = document.createElement('img');
img.src = src;
img.onload = function() {
let w = img.naturalWidth;
let h = img.naturalHeight;
console.log(w); // 0
console.log(h); // 0
}
//$(img).remove();
I have an image uploader in my drawing application that I've written in Javascript. I want to allow the user to place multiple of the same image on the canvas. However, when I try to upload an image that's already on the canvas, nothing happens and a breakpoint in my event handler for the uploader never gets hit. What's going on and how can I fix it? Thanks!
Here's the code for my image handler:
function handleImage(e) {
var reader = new FileReader();
reader.onload = function(event) {
var img = new Image();
img.onload = function() {
img.className = 'drag';
img.style.left = 0;
img.style.top = 0;
context.drawImage(img, parseInt(img.style.left, 10) , parseInt(img.style.top, 10));
images.push(img);
}
img.src = event.target.result;
}
reader.readAsDataURL(e.target.files[0]);
};
I do tend to agree with Rene Pot to use the same image again (duplicate button), but you still can't prevent the user from inserting/loading the same image again. I've encountered the problem a while ago and used this bit of code to check if the image is already cached (if cached, there is no load, hence the onload won't fire either).
var img = new Image();
img.src = event.target.result;
var insertImage = function() {
img.className = 'drag';
img.style.left = 0;
img.style.top = 0;
context.drawImage(img, parseInt(img.style.left, 10) , parseInt(img.style.top, 10));
images.push(img);
}
if(img.complete){
img.onload = insertImage;
} else {
insertImage();
}
Hope that helps.
I'm using html5 to create drag and drop image upload functionality. This works great for me in firefox but in chrome the image onload event only fires the first time. If I drag multiple images in only the first works and if I drag a second in it fails. I believe the problem is with the image onload.
here is the way my code works I have removed the irrelevant sections:
var img = document.createElement("img");
var reader = new FileReader();
var canvas = document.createElement("canvas");
var canvasData;
var ctx = canvas.getContext("2d");
var myFiles;
var i = 0;
reader.onload = (function (aImg)
{
return function (e)
{
aImg.src = e.target.result;
};
})(img);
img.onload = function (){
//resizes image
//draws it to the canvas
//posts to server
i++;
if(i < myFiles.length){
processNext(i);
}
}
function processNext(filei) {
var file = myFiles[filei];
img.file = file;
reader.readAsDataURL(file);
}
i = 0;
myFiles = files;
processNext(0);
Does anyone know why this works in firefox but not chrome?
Explanation from chromium tracker:
This is not a bug. WebKit is just more strict. You must instantiate a new Image() object before the replacement, like this:
var photo = document.getElementById('image_id');
var img = new Image();
img.addEventListener('load', myFunction, false);
img.src = 'http://newimgsource.jpg';
photo.src = img.src;
source: http://code.google.com/p/chromium/issues/detail?id=7731#c12
This is strange, none of the above worked for me. I was defining the image variable as local and change it to global and it started working. Does this make sense? Can somebody explain it?
This didnt worked for me:
function loadImage() {
var ImageToLoad = new Image();
ImageToLoad.onload = function() {
console.log("finish loading");
};
ImageToLoad.src = "myimage.png";
}
This did work:
var ImageToLoad = new Image();
function loadImage() {
ImageToLoad.onload = function() {
console.log("finish loading");
};
ImageToLoad.src = "myimage.png";
}