Get the Size of a CSS Background Image Using JavaScript? - javascript

Is it possible to use JavaScript to get the actual size (width and height in pixels) of a CSS referenced background image?

Yes, and I'd do it like this...
window.onload = function () {
var imageSrc = document
.getElementById('hello')
.style.backgroundImage.replace(/url\((['"])?(.*?)\1\)/gi, '$2')
.split(',')[0];
// I just broke it up on newlines for readability
var image = new Image();
image.src = imageSrc;
image.onload = function () {
var width = image.width,
height = image.height;
alert('width =' + width + ', height = ' + height);
};
};
Some notes...
We need to remove the url() part that JavaScript returns to get the proper image source. We need to split on , in case the element has multiple background images.
We make a new Image object and set its src to the new image.
We can then read the width & height.
jQuery would probably a lot less of a headache to get going.

Can't comment under answers, so here is jQuery version including background-size (posted because this question is first one in google search and may be useful to someone else than me):
function getBackgroundSize(selector, callback) {
var img = new Image(),
// here we will place image's width and height
width, height,
// here we get the size of the background and split it to array
backgroundSize = $(selector).css('background-size').split(' ');
// checking if width was set to pixel value
if (/px/.test(backgroundSize[0])) width = parseInt(backgroundSize[0]);
// checking if width was set to percent value
if (/%/.test(backgroundSize[0])) width = $(selector).parent().width() * (parseInt(backgroundSize[0]) / 100);
// checking if height was set to pixel value
if (/px/.test(backgroundSize[1])) height = parseInt(backgroundSize[1]);
// checking if height was set to percent value
if (/%/.test(backgroundSize[1])) height = $(selector).parent().height() * (parseInt(backgroundSize[0]) / 100);
img.onload = function () {
// check if width was set earlier, if not then set it now
if (typeof width == 'undefined') width = this.width;
// do the same with height
if (typeof height == 'undefined') height = this.height;
// call the callback
callback({ width: width, height: height });
}
// extract image source from css using one, simple regex
// src should be set AFTER onload handler
img.src = $(selector).css('background-image').replace(/url\(['"]*(.*?)['"]*\)/g, '$1');
}
or as jQuery plugin:
(function ($) {
// for better performance, define regexes once, before the code
var pxRegex = /px/, percentRegex = /%/, urlRegex = /url\(['"]*(.*?)['"]*\)/g;
$.fn.getBackgroundSize = function (callback) {
var img = new Image(), width, height, backgroundSize = this.css('background-size').split(' ');
if (pxRegex.test(backgroundSize[0])) width = parseInt(backgroundSize[0]);
if (percentRegex.test(backgroundSize[0])) width = this.parent().width() * (parseInt(backgroundSize[0]) / 100);
if (pxRegex.test(backgroundSize[1])) height = parseInt(backgroundSize[1]);
if (percentRegex.test(backgroundSize[1])) height = this.parent().height() * (parseInt(backgroundSize[0]) / 100);
// additional performance boost, if width and height was set just call the callback and return
if ((typeof width != 'undefined') && (typeof height != 'undefined')) {
callback({ width: width, height: height });
return this;
}
img.onload = function () {
if (typeof width == 'undefined') width = this.width;
if (typeof height == 'undefined') height = this.height;
callback({ width: width, height: height });
}
img.src = this.css('background-image').replace(urlRegex, '$1');
return this;
}
})(jQuery);

var actualImage = new Image();
actualImage.src = $('YOUR SELECTOR HERE').css('background-image').replace(/"/g,"").replace(/url\(|\)$/ig, "");
actualImage.onload = function() {
width = this.width;
height = this.height;
}

var dimension, image;
image = new Image();
image.src = {url/data}
image.onload = function() {
dimension = {
width: image.naturalWidth,
height: image.naturalHeight
};
console.log(dimension); // Actual image dimension
};

Here it is in jQuery:
var actualImage = new Image();
actualImage.src = $('YOUR SELECTOR HERE').css('background-image').replace(/"/g,"").replace(/url\(|\)$/ig, "");
actualImage.width // The actual image width
actualImage.height // The actual image height
Thanks for the sweet regex alex.

If you're using React you can create a custom hook:
import { useEffect, useState, useCallback, useRef } from 'react'
const urlRgx = /url\((['"])?(.+?)\1\)/
const getImagePromise = src =>
new Promise(resolve => {
const img = new Image()
img.onload = () =>
resolve({
src,
width: img.naturalWidth,
height: img.naturalHeight
})
img.src = src
})
const useBackgroundImageSize = (asCallbackFlagOrUrls = false) => {
const ref = useRef()
const [images, setImages] = useState(null)
const callback = useCallback(async () => {
if (Array.isArray(asCallbackFlagOrUrls)) {
const imgPromises = asCallbackFlagOrUrls.map(getImagePromise)
const imgs = await Promise.all(imgPromises)
if (ref?.current) {
setImages(imgs)
}
}
if (typeof asCallbackFlagOrUrls === 'string') {
const image = await getImagePromise(asCallbackFlagOrUrls)
if (ref?.current) {
setImages(image)
}
}
if (typeof asCallbackFlagOrUrls === 'boolean') {
if (ref.current) {
const matches = window
.getComputedStyle(ref.current)
.backgroundImage.match(new RegExp(urlRgx, 'g'))
if (Array.isArray(matches)) {
const imgPromises = matches.map(match =>
getImagePromise(match.replace(new RegExp(urlRgx), '$2'))
)
const imgs = await Promise.all(imgPromises)
if (ref?.current) {
setImages(imgs.length > 1 ? imgs : imgs[0])
}
}
}
}
}, [ref, asCallbackFlagOrUrls])
useEffect(() => {
if (asCallbackFlagOrUrls !== true) {
callback()
}
}, [asCallbackFlagOrUrls, callback])
return asCallbackFlagOrUrls === true ? [ref, images, callback] : [ref, images]
}
export { useBackgroundImageSize }
Then use it like:
const App = () => {
const [ref, image] = useBackgroundImageSize()
console.log(image) // { width, height, src }
return <div ref={ref} image={image} />
}
You can also install background-image-size-hook and use it as a dependency. See the README for more usage details.

Here is a fixed version of the code from klh's post.
I pointed out some small mistakes on the comment section of his post and was told please edit it.
And so I did.
However, reviewers Jan Wilamowski and Dave rejected it.
"This edit was intended to address the author of the post and makes no sense as an edit. It should have been written as a comment or an answer."
Apparently they did not see the comments section.
I had no choice but to write the revised code as a new answer.
function getBackgroundSize(selector, callback) {
var img = new Image(),
// here we will place image's width and height
width, height,
// here we get the size of the background and split it to array
backgroundSize = $(selector).css('background-size').split(' ');
// checking if width was set to pixel value
if (/px/.test(backgroundSize[0])) width = parseInt(backgroundSize[0]);
// checking if width was set to percent value
if (/%/.test(backgroundSize[0])) width = $(selector).width() * (parseInt(backgroundSize[0]) / 100);
// checking if height was set to pixel value
if (/px/.test(backgroundSize[1])) height = parseInt(backgroundSize[1]);
// checking if height was set to percent value
if (/%/.test(backgroundSize[1])) height = $(selector).height() * (parseInt(backgroundSize[1]) / 100);
img.onload = function () {
// check if width was set earlier, if not then set it now
if (typeof width == 'undefined') width = this.width;
// do the same with height
if (typeof height == 'undefined') height = this.height;
// call the callback
callback({ width: width, height: height });
}
// extract image source from css using one, simple regex
// src should be set AFTER onload handler
img.src = $(selector).css('background-image').replace(/url\(['"]*(.*?)['"]*\)/g, '$1');
}
JQuery
(function ($) {
// for better performance, define regexes once, before the code
var pxRegex = /px/, percentRegex = /%/, urlRegex = /url\(['"]*(.*?)['"]*\)/g;
$.fn.getBackgroundSize = function (callback) {
var img = new Image(), width, height, backgroundSize = this.css('background-size').split(' ');
if (pxRegex.test(backgroundSize[0])) width = parseInt(backgroundSize[0]);
if (percentRegex.test(backgroundSize[0])) width = this.width() * (parseInt(backgroundSize[0]) / 100);
if (pxRegex.test(backgroundSize[1])) height = parseInt(backgroundSize[1]);
if (percentRegex.test(backgroundSize[1])) height = this.height() * (parseInt(backgroundSize[1]) / 100);
// additional performance boost, if width and height was set just call the callback and return
if ((typeof width != 'undefined') && (typeof height != 'undefined')) {
callback({ width: width, height: height });
return this;
}
img.onload = function () {
if (typeof width == 'undefined') width = this.width;
if (typeof height == 'undefined') height = this.height;
callback({ width: width, height: height });
}
img.src = this.css('background-image').replace(urlRegex, '$1');
return this;
}
})(jQuery);

Related

Get natural dimensions in lazy loading mechanism

I need to adjust image sizes in a lazy loading mechanism. The final image paths are stored in attribute data-src, if lazy loading is enabled.
For optical reasons, I don't want to wait until lazy loading is done, so I've tried the following:
window.addEventListener('load', function() {
const aImages = document.getElementsByClassName('article-image');
for ( var i=0;i<aImages.length;i++ ) {
const wrp = aImages[i].parentElement;
var imgHeight, imgWidth;
// if lazyload
if ( aImages[i].getAttribute('data-src') ) {
var img = new Image();
img.onload = function() { imgHeight = this.naturalHeight; imgWidth = this.naturalWidth };
img.src = aImages[i].getAttribute('data-src');
} else {
imgHeight = aImages[i].naturalHeight;
imgWidth = aImages[i].naturalWidth;
}
var dim = calcAspectRatioFit(imgWidth, imgHeight, wrp.clientWidth, wrp.clientHeight);
console.log('['+i+']\n' + 'dim.width: '+dim.width + '\ndim.height: '+dim.height + '\ntypeof(wrp): '+typeof(wrp) + '\nwrp.clientWidth: '+wrp.clientWidth + '\nwrp.clientHeight: '+wrp.clientHeight + '\nimgWidth: '+imgWidth + '\nimgHeight: '+imgHeight);
aImages[i].style.setProperty('width', dim.width + 'px', 'important');
aImages[i].style.setProperty('height', dim.height + 'px', 'imoprtant');
}
});
Guess the problem is the onload-function. If I set a breakpoint between it and before calcAspectRatioFit(), everything works as excepted. Guess 'img' then has enough time to load.
Debug-Output from console.log():
[0]
dim.width: NaN
dim.height: NaN
typeof(wrp): object
wrp.clientWidth: 222
wrp.clientHeight: 192
imgWidth: undefined
imgHeight: undefined
Any ideas how to solve this?
// Edit 2:
Of course, the problem was, that the last four lines didn't wait for img.onload() to be executed. Thanks #Peter Krebs for this hint.
Here is a QnD solution which works fine. (Added anonymous wrapper fnc to copy i)
window.addEventListener('load', function() {
const aImages = document.getElementsByClassName('article-image');
const exec = function(i) {
const wrp = aImages[i].parentElement;
var dim = calcAspectRatioFit(aImages[i].naturalWidth, aImages[i].naturalHeight, wrp.clientWidth, wrp.clientHeight);
aImages[i].style.setProperty('width', dim.width + 'px');
aImages[i].style.setProperty('height', dim.height + 'px');
}
for ( var i=0;i<aImages.length;i++ ) {
if ( aImages[i].getAttribute('data-src') ) {
aImages[i].onload = (function(i) { return function() { exec(i) } })(i);
this.src = aImages[i].getAttribute('data-src');
} else { exec(i) }
}
});

Match image container width with image width after it is rendered - React

I am using react-image-marker which overlays marker on image inside a div.
<ImageMarker
src={props.asset.url}
markers={markers}
onAddMarker={(marker) => setMarkers([...markers, marker])}
className="object-fit-contain image-marker__image"
/>
The DOM elements are as follows:
<div class=“image-marker”>
<img src=“src” class=“image-marker__image” />
</div>
To make vertically long images fit the screen i have added css to contain the image within div
.image-marker {
width: inherit;
height: inherit;
}
.image-marker__image {
object-fit:contain !important;
width: inherit;
height: inherit;
}
But now the image is only a subpart of the entire marker area. Due to which marker can be added beyond image bounds, which i do not want.
How do you think i can tackle this. After the image has been loaded, how can i change the width of parent div to make sure they have same size and markers remain in the image bounds. Please specify with code if possible
Solved it by adding event listeners in useLayoutEffect(). Calculating image size info after it is rendered and adjusting the parent div dimensions accordingly. Initially and also when resize occurs.
If you think you have a better solution. Do specify.
useLayoutEffect(() => {
const getRenderedSize = (contains, cWidth, cHeight, width, height, pos) => {
var oRatio = width / height,
cRatio = cWidth / cHeight;
return function () {
if (contains ? (oRatio > cRatio) : (oRatio < cRatio)) {
this.width = cWidth;
this.height = cWidth / oRatio;
} else {
this.width = cHeight * oRatio;
this.height = cHeight;
}
this.left = (cWidth - this.width) * (pos / 100);
this.right = this.width + this.left;
return this;
}.call({});
}
const getImgSizeInfo = (img) => {
var pos = window.getComputedStyle(img).getPropertyValue('object-position').split(' ');
return getRenderedSize(true,
img.width,
img.height,
img.naturalWidth,
img.naturalHeight,
parseInt(pos[0]));
}
const imgDivs = reactDom.findDOMNode(imageCompRef.current).getElementsByClassName("image-marker__image")
if (imgDivs) {
if (imgDivs.length) {
const thisImg = imgDivs[0]
thisImg.addEventListener("load", (evt) => {
if (evt) {
if (evt.target) {
if (evt.target.naturalWidth && evt.target.naturalHeight) {
let renderedImgSizeInfo = getImgSizeInfo(evt.target)
if (renderedImgSizeInfo) {
setOverrideWidth(Math.round(renderedImgSizeInfo.width))
}
}
}
}
})
}
}
function updateSize() {
const thisImg = imgDivs[0]
if (thisImg){
let renderedImgSizeInfo = getImgSizeInfo(thisImg)
if (renderedImgSizeInfo) {
setOverrideWidth((prev) => {
return null
})
setTimeout(() => {
setOverrideWidth((prev) => {
return setOverrideWidth(Math.round(renderedImgSizeInfo.width))
})
}, 390);
}
}
}
window.addEventListener('resize', updateSize);
return () => window.removeEventListener('resize', updateSize);
}, [])

How to read an image from the localhost url and get its width and height in javascript

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))

Check image width and height before upload with Javascript

I have a JPS with a form in which a user can put an image:
<div class="photo">
<div>Photo (max 240x240 and 100 kb):</div>
<input type="file" name="photo" id="photoInput" onchange="checkPhoto(this)"/>
</div>
I have written this js:
function checkPhoto(target) {
if(target.files[0].type.indexOf("image") == -1) {
document.getElementById("photoLabel").innerHTML = "File not supported";
return false;
}
if(target.files[0].size > 102400) {
document.getElementById("photoLabel").innerHTML = "Image too big (max 100kb)";
return false;
}
document.getElementById("photoLabel").innerHTML = "";
return true;
}
which works fine to check file type and size. Now I want to check image width and height but I cannot do it.
I have tried with target.files[0].width but I get undefined. With other ways I get 0.
Any suggestions?
The file is just a file, you need to create an image like so:
var _URL = window.URL || window.webkitURL;
$("#file").change(function (e) {
var file, img;
if ((file = this.files[0])) {
img = new Image();
var objectUrl = _URL.createObjectURL(file);
img.onload = function () {
alert(this.width + " " + this.height);
_URL.revokeObjectURL(objectUrl);
};
img.src = objectUrl;
}
});
Demo: http://jsfiddle.net/4N6D9/1/
I take it you realize this is only supported in a few browsers. Mostly firefox and chrome, could be opera as well by now.
P.S. The URL.createObjectURL() method has been removed from the MediaStream interface. This method has been deprecated in 2013 and superseded by assigning streams to HTMLMediaElement.srcObject. The old method was removed because it is less safe, requiring a call to URL.revokeOjbectURL() to end the stream. Other user agents have either deprecated (Firefox) or removed (Safari) this feature feature.
For more information, please refer here.
In my view the perfect answer you must required is
var reader = new FileReader();
//Read the contents of Image File.
reader.readAsDataURL(fileUpload.files[0]);
reader.onload = function (e) {
//Initiate the JavaScript Image object.
var image = new Image();
//Set the Base64 string return from FileReader as source.
image.src = e.target.result;
//Validate the File Height and Width.
image.onload = function () {
var height = this.height;
var width = this.width;
if (height > 100 || width > 100) {
alert("Height and Width must not exceed 100px.");
return false;
}
alert("Uploaded image has valid Height and Width.");
return true;
};
};
I agree. Once it is uploaded to somewhere the user's browser can access then it is pretty easy to get the size. As you need to wait for the image to load you'll want to hook into the onload event for img.
Updated example:
// async/promise function for retrieving image dimensions for a URL
function imageSize(url) {
const img = document.createElement("img");
const promise = new Promise((resolve, reject) => {
img.onload = () => {
// Natural size is the actual image size regardless of rendering.
// The 'normal' `width`/`height` are for the **rendered** size.
const width = img.naturalWidth;
const height = img.naturalHeight;
// Resolve promise with the width and height
resolve({width, height});
};
// Reject promise on error
img.onerror = reject;
});
// Setting the source makes it start downloading and eventually call `onload`
img.src = url;
return promise;
}
// How to use in an async function
(async() => {
const imageUrl = 'http://your.website.com/userUploadedImage.jpg';
const imageDimensions = await imageSize(imageUrl);
console.info(imageDimensions); // {width: 1337, height: 42}
})();
Older example:
var width, height;
var img = document.createElement("img");
img.onload = function() {
// `naturalWidth`/`naturalHeight` aren't supported on <IE9. Fallback to normal width/height
// The natural size is the actual image size regardless of rendering.
// The 'normal' width/height are for the **rendered** size.
width = img.naturalWidth || img.width;
height = img.naturalHeight || img.height;
// Do something with the width and height
}
// Setting the source makes it start downloading and eventually call `onload`
img.src = "http://your.website.com/userUploadedImage.jpg";
This is the easiest way to check the size
let img = new Image()
img.src = window.URL.createObjectURL(event.target.files[0])
img.onload = () => {
alert(img.width + " " + img.height);
}
Check for specific size. Using 100 x 100 as example
let img = new Image()
img.src = window.URL.createObjectURL(event.target.files[0])
img.onload = () => {
if(img.width === 100 && img.height === 100){
alert(`Nice, image is the right size. It can be uploaded`)
// upload logic here
} else {
alert(`Sorry, this image doesn't look like the size we wanted. It's
${img.width} x ${img.height} but we require 100 x 100 size image.`);
}
}
Attach the function to the onchange method of the input type file /onchange="validateimg(this)"/
function validateimg(ctrl) {
var fileUpload = ctrl;
var regex = new RegExp("([a-zA-Z0-9\s_\\.\-:])+(.jpg|.png|.gif)$");
if (regex.test(fileUpload.value.toLowerCase())) {
if (typeof (fileUpload.files) != "undefined") {
var reader = new FileReader();
reader.readAsDataURL(fileUpload.files[0]);
reader.onload = function (e) {
var image = new Image();
image.src = e.target.result;
image.onload = function () {
var height = this.height;
var width = this.width;
if (height < 1100 || width < 750) {
alert("At least you can upload a 1100*750 photo size.");
return false;
}else{
alert("Uploaded image has valid Height and Width.");
return true;
}
};
}
} else {
alert("This browser does not support HTML5.");
return false;
}
} else {
alert("Please select a valid Image file.");
return false;
}
}
const ValidateImg = (file) =>{
let img = new Image()
img.src = window.URL.createObjectURL(file)
img.onload = () => {
if(img.width === 100 && img.height ===100){
alert("Correct size");
return true;
}
alert("Incorrect size");
return true;
}
}
I think this may be the simplest for uploads if you want to use it other functions.
async function getImageDimensions(file) {
let img = new Image();
img.src = URL.createObjectURL(file);
await img.decode();
let width = img.width;
let height = img.height;
return {
width,
height,
}
}
Use like
const {width, height } = await getImageDimensions(file)
Suppose you were storing an image for Tiger taken in Kenya. So you could use it like to upload to cloud storage and then store photo information.
const addImage = async (file, title, location) => {
const { width, height } = await getImageDimensions(file)
const url = await uploadToCloudStorage(file) // returns storage url
await addToDatabase(url, width, height, title, location)
}
function validateimg(ctrl) {
var fileUpload = $("#txtPostImg")[0];
var regex = new RegExp("([a-zA-Z0-9\s_\\.\-:])+(.jpg|.png|.gif)$");
if (regex.test(fileUpload.value.toLowerCase())) {
if (typeof (fileUpload.files) != "undefined") {
var reader = new FileReader();
reader.readAsDataURL(fileUpload.files[0]);
reader.onload = function (e) {
var image = new Image();
image.src = e.target.result;
image.onload = function () {
var height = this.height;
var width = this.width;
console.log(this);
if ((height >= 1024 || height <= 1100) && (width >= 750 || width <= 800)) {
alert("Height and Width must not exceed 1100*800.");
return false;
}
alert("Uploaded image has valid Height and Width.");
return true;
};
}
} else {
alert("This browser does not support HTML5.");
return false;
}
} else {
alert("Please select a valid Image file.");
return false;
}
}
You can do the steps for previewing the image without showing it which is supported on all browsers. Following js code shows you how to check the width and height :
var file = e.target.files[0];
if (/\.(jpe?g|png|gif)$/i.test(file.name)) {
var reader = new FileReader();
reader.addEventListener("load", function () {
var image = new Image();
image.src = this.result as string;
image.addEventListener('load', function () {
console.log(`height: ${this.height}, width: ${this.width}`);
});
}, false);
reader.readAsDataURL(file);
}
Based on Mozilla docs:
The readAsDataURL method is used to read the contents of the specified
Blob or File. When the read operation is finished, the readyState
becomes DONE, and the loadend is triggered. At that time, the result
attribute contains the data as a data: URL representing the file's
data as a base64 encoded string.
And the browser compatibility is listed too.
In my case, I needed to also prevent the form from being submited, so here is the solution that worked for me.
The preventDefault will stop the form action, then we check the size and dimensions of the image in the onload function.
If all good, we allow the submit.
As the submit button gets disabled if a user still tries to submit the form with an invalid image, I also had to re-able the submit button once a valid image is inputted.
const validateMaxImageFileSize = (e) => {
e.preventDefault();
const el = $("input[type='file']")[0];
if (el.files && el.files[0]) {
const file = el.files[0];
const maxFileSize = 5242880; // 5 MB
const maxWidth = 1920;
const maxHeight = 1080;
const img = new Image();
img.src = window.URL.createObjectURL(file);
img.onload = () => {
if (file.type.match('image.*') && file.size > maxFileSize) {
alert('The selected image file is too big. Please choose one that is smaller than 5 MB.');
} else if (file.type.match('image.*') && (img.width > maxWidth || img.height > maxHeight)) {
alert(`The selected image is too big. Please choose one with maximum dimensions of ${maxWidth}x${maxHeight}.`);
} else {
e.target.nodeName === 'INPUT'
? (e.target.form.querySelector("input[type='submit']").disabled = false)
: e.target.submit();
}
};
}
};
$('form.validate-image-size').on('submit', validateMaxImageFileSize);
$("form.validate-image-size input[type='file']").on('change', validateMaxImageFileSize);
function uploadfile(ctrl) {
var validate = validateimg(ctrl);
if (validate) {
if (window.FormData !== undefined) {
ShowLoading();
var fileUpload = $(ctrl).get(0);
var files = fileUpload.files;
var fileData = new FormData();
for (var i = 0; i < files.length; i++) {
fileData.append(files[i].name, files[i]);
}
fileData.append('username', 'Wishes');
$.ajax({
url: 'UploadWishesFiles',
type: "POST",
contentType: false,
processData: false,
data: fileData,
success: function(result) {
var id = $(ctrl).attr('id');
$('#' + id.replace('txt', 'hdn')).val(result);
$('#imgPictureEn').attr('src', '../Data/Wishes/' + result).show();
HideLoading();
},
error: function(err) {
alert(err.statusText);
HideLoading();
}
});
} else {
alert("FormData is not supported.");
}
}

Determine original size of image cross browser?

Is there a reliable, framework independent way of determining the physical dimensions of a <img src='xyz.jpg'> resized on the client side?
You have 2 options:
Option 1:
Remove the width and height attributes and read offsetWidth and offsetHeight
Option 2:
Create a JavaScript Image object, set the src, and read the width and height (you don't even have to add it to the page to do this).
function getImgSize(imgSrc) {
var newImg = new Image();
newImg.onload = function() {
var height = newImg.height;
var width = newImg.width;
alert ('The image size is '+width+'*'+height);
}
newImg.src = imgSrc; // this must be done AFTER setting onload
}
Edit by Pekka: As agreed in the comments, I changed the function to run on the ´onload´ event of the image. Otherwise, with big images, height and width would not return anything because the image was not loaded yet.
Images (on Firefox at least) have a naturalWidth/height property so you can use img.naturalWidth to get the original width
var img = document.getElementsByTagName("img")[0];
img.onload=function(){
console.log("Width",img.naturalWidth);
console.log("Height",img.naturalHeight);
}
Source
You can preload the image into a javascript Image object, then check the width and height properties on that object.
/* Function to return the DOM object's in crossbrowser style */
function widthCrossBrowser(element) {
/* element - DOM element */
/* For FireFox & IE */
if( element.width != undefined && element.width != '' && element.width != 0){
this.width = element.width;
}
/* For FireFox & IE */
else if(element.clientWidth != undefined && element.clientWidth != '' && element.clientWidth != 0){
this.width = element.clientWidth;
}
/* For Chrome * FireFox */
else if(element.naturalWidth != undefined && element.naturalWidth != '' && element.naturalWidth != 0){
this.width = element.naturalWidth;
}
/* For FireFox & IE */
else if(element.offsetWidth != undefined && element.offsetWidth != '' && element.offsetWidth != 0){
this.width = element.offsetWidth;
}
/*
console.info(' widthWidth width:', element.width);
console.info(' clntWidth clientWidth:', element.clientWidth);
console.info(' natWidth naturalWidth:', element.naturalWidth);
console.info(' offstWidth offsetWidth:',element.offsetWidth);
console.info(' parseInt(this.width):',parseInt(this.width));
*/
return parseInt(this.width);
}
var elementWidth = widthCrossBrowser(element);
Just changing a little bit Gabriel's second option, to be more easy to use:
function getImgSize(imgSrc, callback) {
var newImg = new Image();
newImg.onload = function () {
if (callback != undefined)
callback({width: newImg.width, height: newImg.height})
}
newImg.src = imgSrc;
}
Html:
<img id="_temp_circlePic" src="http://localhost/myimage.png"
style="width: 100%; height:100%">
Sample call:
getImgSize($("#_temp_circlePic").attr("src"), function (imgSize) {
// do what you want with the image's size.
var ratio = imgSize.height / $("#_temp_circlePic").height();
});
Adding adjustments to Gabriel's second option to help people working with react-grid-gallery.
const [images, setImages] = useState([])
const getImgSize = function (imgSrc, index) {
var newImg = new Image()
newImg.onload = function () {
setImages((images) => [
...images,
{
id: index,
src: imgSrc,
thumbnail: imgSrc,
width: newImg.width,
height: newImg.height,
},
])
}
newImg.src = imgSrc
}
In useEffect you can call this method
gallery_urls?.map((url, index) => {
getImgSize(url, index)
})

Categories