I have a Base64 image encoded that you can find here. How can I get the height and the width of it?
var i = new Image();
i.onload = function(){
alert(i.width + ", " + i.height);
};
i.src = imageData;
For synchronous use just wrap it into a promise like this:
function getImageDimensions(file) {
return new Promise (function (resolved, rejected) {
var i = new Image()
i.onload = function(){
resolved({w: i.width, h: i.height})
};
i.src = file
})
}
then you can use await to get the data in synchronous coding style:
var dimensions = await getImageDimensions(file)
I found that using .naturalWidth and .naturalHeight had the best results.
const img = new Image();
img.src = 'https://via.placeholder.com/350x150';
img.onload = function() {
const imgWidth = img.naturalWidth;
const imgHeight = img.naturalHeight;
console.log('imgWidth: ', imgWidth);
console.log('imgHeight: ', imgHeight);
};
Documentation:
HTMLImageElement.naturalWidth
HTMLImageElement.naturalHeight
This is only supported in modern browsers. NaturalWidth and NaturalHeight in IE
A more modern solution is to use HTMLImageElement.decode() instead of the onload event. decode() returns a promise and thus can be used synchronously with await.
Asynchronous use:
let img = new Image();
img.src = "myImage.png";
img.decode().then(() => {
let width = img.width;
let height = img.height;
// Do something with dimensions
});
Synchronous use (inside an async function):
let img = new Image();
img.src = "myImage.png";
await img.decode();
let width = img.width;
let height = img.height;
// Do something with dimensions
Create a hidden <img> with that image and then use jQuery's .width() and . height()
$("body").append("<img id='hiddenImage' src='" + imageData + "' />");
var width = $('#hiddenImage').width();
var height = $('#hiddenImage').height();
$('#hiddenImage').remove();
alert("width:" + width + " height:" + height);
Test here: JSFiddle
The image is not initially created hidden. It gets created, and then you get width and height and then remove it. This may cause a very short visibility in large images. In this case, you have to wrap the image in another container and make that container hidden, not the image itself.
Another Fiddle that does not add to the DOM as per gp.'s answer:
here
Related
Hey guys I am new to javascript and react, I want to get the image's width and height when its loaded from the image url. How to do it? Help would be much appreciated.
I know it starts with this but doesn't really understand how to continue..
const imageDimension = (img) => {
let reader = new FileReader();
}
Thanks
You can use the load event:
const image = new Image();
image.addEventListener('load', () => {
console.log('image height', image.height);
console.log('image width', image.width);
})
image.src = 'http://localhost/image.png'
The "load" event listener works if the image is going to be loaded in the browser.
However, if that is not the case, and you really don't want the image to be visible then you could do this.
const getImageDimension = (imgUrl) => {
const img = new Image();
// set some styles to hide the img
img.src = imgUrl;
img.style.left = -9999;
img.style.position = 'absolute';
img.style.visibility = 'hidden';
// inject it into the page
document.body.appendChild(img);
// resolve when image has been injected and
// img.height and width is available
return new Promise((resolve) => {
const interval = setInterval(() => {
const height = img.naturalHeight;
const width = img.naturalWidth;
if (height && width) {
clearInterval(interval);
document.body.removeChild(img);
resolve({
height,
width,
})
}
})
})
}
const SAMPLE_IMAGE = "https://asia.olympus-imaging.com/content/000107507.jpg";
getImageDimension(SAMPLE_IMAGE)
.then((dimension) => console.log(dimension))
I'm using AngularJS and TypeScript. I am using the cytoscape library with the extension cytoscape-edgehandles and the wrapper ngCytoscape for AngularJS. I am trying to add an image to the hover handle of the nodes, however the implementation of the drawImage method in cytoscape-edgehandles 2.7.1 does not wait for the image to load before drawing, therefore a range error occurs.
I have tried to give the cytoscape graph the options after the image is loaded, however the cytoscape graph expects the options to immediately be available for use. So somehow I need to load the image before passing it to the graph.
In the constructor of the controller:
this.$scope.ehOptions = this.GetEhOptions();
The get EhOptions method:
protected GetEhOptions(): GraphModels.EhOptions {
var options = new GraphModels.EhOptions;
var img = new Image();
img.width = 25;
img.height = 25
img.src = "../../Content/icons/ic_circle_add_24px.svg";
options.handleImage = img;
img.addEventListener('load', e => {
return options;
});
}
This results in the options never being loaded by the graph. If I do this in stead, I get all the options, except the image:
var options = new GraphModels.EhOptions;
var img = new Image();
img.width = 25;
img.height = 25
img.src = "../../Content/icons/ic_circle_add_24px.svg";
img.addEventListener('load', e => {
options.handleImage = img;
});
return options;
The code of cytoscape-edgehandles concerning the handleIcon:
if(options().handleIcon){
var icon = options().handleIcon;
var width = icon.width*cy.zoom(), height = icon.height*cy.zoom();
ctx.drawImage(icon, hx-(width/2), hy-(height/2), width, height);
}
If it is changed to this, then it works:
if (true) {
var img = new Image();
var width = 25 * cy.zoom();
var height = 25 * cy.zoom();
img.width = width;
img.height = height
img.src = "../../Content/icons/ic_circle_add_24px.svg";
img.addEventListener('load', e => {
ctx.drawImage(img, hx - (width/2), hy - (height/2), width, height)
})
}
However, I cannot change the library code.
Hope you have any ideas. Thanks!
Create an AngularJS promise:
protected GetEhOptions(): GraphModels.EhOptions {
var deferred = $q.defer();
var options = new GraphModels.EhOptions;
var img = new Image();
img.width = 25;
img.height = 25
img.src = "../../Content/icons/ic_circle_add_24px.svg";
options.handleImage = img;
img.addEventListener('load', e => {
̶r̶e̶t̶u̶r̶n̶ ̶o̶p̶t̶i̶o̶n̶s̶;̶
deferred.resolve(options);
});
img.addEventListener('error', e => {
deferred.reject(e);
});
return deferred.promise;
}
Then extract the options from the returned promise:
this.GetEhOptions().then(options => {
this.$scope.ehOptions = options;
});
For more information, see
AngularJS $q Service API Reference - The Deferred API
I don't have any idea about cytoscape, but try this,
options:any = new GraphModels.EhOptions;
let globleThis = this;
var img = new Image();
img.width = 25;
img.height = 25
img.src = "../../Content/icons/ic_circle_add_24px.svg";
this.options.handleImage = img;
img.addEventListener('load', e => {
this.GetEhOptions(globleThis.options);
});
protected GetEhOptions(options): GraphModels.EhOptions {
return options;
}
or
var options = new GraphModels.EhOptions;
var img = new Image();
img.width = 25;
img.height = 25
img.src = "../../Content/icons/ic_circle_add_24px.svg";
img.addEventListener('load', e => {
return options.handleImage = img;
});
No experiance with a specific library but I worked with similar ones. In those cases I wrapped it into my own directive and then controlled the creation from there directly. In that case you have access to the $element and you can create it on the fly.
I don't know how to get image width and height synchronously. Please correct the below code.
I have tried many ways to get image width and height in direct way.
getImageSize(url){
var img = new Image()
img.src = url
img.onload = function(){
return [img.width, img.height]
}
}
getImageUrl(obj){
let vm = this
let reader = new FileReader()
reader.readAsDataURL(obj)
reader.onload = function() {
return reader.result
}
}
async getImageSize(imgObj){
let base64URI = await this.getImageUrl(imgObj)
let size = await this.getImageSize(base64URI)
return size
}
beforeuploadImage(event){
let imgsize = this.getImageSize(imgObj)
imgsize = imgsize.split(",")
console.log(imgsize[0], imgsize[1])
}
I need to get image width and height in beforeuploadImage method directly
I want to resize a background image 30% to its original size then use it as background to an element. I am sure my mistake is somewhere in the last line.
Here is my code :
var img = new Image();
img.src = "wallpaper.jpg";
var a = img.height;
var newWidth = (img.width*0.3));
var newHeight = (img.height*0.3));
t.getBody().style.backgroundImage = "url("+img.src+")";
t.getBody().style.backgroundSize = "(newWidth)px (newHeight)px";
Values of background-size property should be like Xpx Ypx. Try change Your last line to this:
t.getBody().style.backgroundSize = newWidth+"px "+newHeight+"px";
substitute the newWidth and newHeight values with a space in between.
var img = new Image();
img.src = "wallpaper.jpg";
var a = img.height;
var newWidth = (parseInt(img.width)*0.3);
var newHeight = (parseInt(img.height)*0.3);
t.getBody().style.backgroundImage = "url("+img.src+")";
t.getBody().style.backgroundSize = newWidth+"px "+newHeight+"px";
I have a Base64 image encoded that you can find here. How can I get the height and the width of it?
var i = new Image();
i.onload = function(){
alert(i.width + ", " + i.height);
};
i.src = imageData;
For synchronous use just wrap it into a promise like this:
function getImageDimensions(file) {
return new Promise (function (resolved, rejected) {
var i = new Image()
i.onload = function(){
resolved({w: i.width, h: i.height})
};
i.src = file
})
}
then you can use await to get the data in synchronous coding style:
var dimensions = await getImageDimensions(file)
I found that using .naturalWidth and .naturalHeight had the best results.
const img = new Image();
img.src = 'https://via.placeholder.com/350x150';
img.onload = function() {
const imgWidth = img.naturalWidth;
const imgHeight = img.naturalHeight;
console.log('imgWidth: ', imgWidth);
console.log('imgHeight: ', imgHeight);
};
Documentation:
HTMLImageElement.naturalWidth
HTMLImageElement.naturalHeight
This is only supported in modern browsers. NaturalWidth and NaturalHeight in IE
A more modern solution is to use HTMLImageElement.decode() instead of the onload event. decode() returns a promise and thus can be used synchronously with await.
Asynchronous use:
let img = new Image();
img.src = "myImage.png";
img.decode().then(() => {
let width = img.width;
let height = img.height;
// Do something with dimensions
});
Synchronous use (inside an async function):
let img = new Image();
img.src = "myImage.png";
await img.decode();
let width = img.width;
let height = img.height;
// Do something with dimensions
Create a hidden <img> with that image and then use jQuery's .width() and . height()
$("body").append("<img id='hiddenImage' src='" + imageData + "' />");
var width = $('#hiddenImage').width();
var height = $('#hiddenImage').height();
$('#hiddenImage').remove();
alert("width:" + width + " height:" + height);
Test here: JSFiddle
The image is not initially created hidden. It gets created, and then you get width and height and then remove it. This may cause a very short visibility in large images. In this case, you have to wrap the image in another container and make that container hidden, not the image itself.
Another Fiddle that does not add to the DOM as per gp.'s answer:
here