Get the Size of a CSS Background Image Using JavaScript

Get the Size of a CSS Background Image Using JavaScript?

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 I get background-image source's size by javascript?

If you want to get the actual width and height of a background image then you can follow these steps

Get the background image's URL like this (https://stackoverflow.com/a/45010803/1391805)

var css = document.getElementById("myElem").style.backgroundImage;
var img = css.replace(/(?:^url\(["']?|["']?\)$)/g, "");

Once you have the image URL do this

var newImg = new Image();
newImg.onload = function(e) {
console.log( this.naturalWidth ); // This is the width you are looking for
console.log( this.naturalHeight ); // .. similarly the height.
}
newImg.src = "img.jpg";

Given the fact that this loads an image first you may want to use this carefully, if this is something that does not apply for a lot of images on a single page then this may not be a performance degrade but if the scale is larger then you may consider something better than loading an image on the client side to fetch its actual dimension.

Getting dimensions of background-image

The issue is that some browsers add quotes to the CSS, and it was trying to load (in the fiddle's case) "http://fiddle.jshell.net/_display/%22http://placehold.it/200x300%22". I've updated your .replace() to look for " as well, and a fiddle is at http://jsfiddle.net/4uMEq/

$('#test').on('click', function () {
$(this).text(getDimensions($(this)));
});

var getDimensions = function (item) {
var img = new Image();
img.src = item.css('background-image').replace(/url\(|\)$|"/ig, '');
return img.width + ' ' + img.height;
};

Getting the height of a background image resized using background-size: contain

The key is to use the static image's dimensions, calculate the aspect ratio of the image, and then use the actual element's dimensions to figure out the computed dimensions of the resized image.

For instance, lets assume you had the following:

html, body { height:100%; }
body {
background-image: url('http://placehold.it/50x100');
background-repeat: no-repeat;
background-size: 100% auto;
}

The static image's dimensions are 50x100, and it is sized to take up a width of 100% of the body element. Therefore the body element's width would be equal to the resized image's width. If you wanted to calculate the resized height of the image, you would just use the image's aspect ratio. In this case, the image's resized height would be 800px, because (400*100)/50 = 800

EXAMPLE HERE

var img = new Image();
img.src = $('body').css('background-image').replace(/url\(|\)$/ig, "");

$(window).on("resize", function () {
$('body').height($('body').width() * img.height / img.width);
}).resize();

Pure JS approach: EXAMPLE HERE

var img = new Image();
img.src = window.getComputedStyle(document.body).getPropertyValue("background-image").replace(/url\(|\)$/ig, "");

function resize(){
var bgHeight = document.body.offsetWidth * img.height / img.width;
document.body.style.height = bgHeight + 'px';
}
window.onresize = resize; resize();

The pure JS method is going to be the fastest, as demonstrated by this jsPerf example.

How to get the current, real , background image size, when background-size is cover?

I found the solution by myself. Here is a nice jsfiddle visualization, where we calculate the container size and the actual background image size separately.

You can resize the image container (red border) by dragging it from the bottom right corner and see how the container size changes separately from the actual background size: https://jsfiddle.net/ahvonenj/o76k5jbx/

$(document).ready(function()
{
var fullhdWidth = 1920;
var fullhdHeight = 1080;
var fullhdRatio = fullhdWidth / fullhdHeight; // About 1.7

$('#wrapper').resize(function()
{
var containerWidth = $(this).width();
var containerHeight = $(this).height();
var containerRatio = containerWidth / containerHeight;
var realWidth = null;
var realHeight = null;

console.log(containerWidth, containerHeight, containerRatio);

if(containerRatio > fullhdRatio)
{
realWidth = containerWidth;
realHeight = containerWidth/fullhdRatio;
}
else
{
realWidth = containerHeight*fullhdRatio;
realHeight = containerHeight;
}
});
});

Note: I am using this small library to detect size changes on the container div element, as jQuery's resize handler can only be bound to window object.

Background Size: Contain, get Size after scale

CSS property background-size: contain; scales the image to the largest so that both the height and width will fit inside, retaining the same aspect ratio of course.

Just like @Teemu said, A background image is a kinda pseudo element which you actually can't refer. But I can show you a workaround on how to get the real image size and compute the scaled background-image size.

It works like ratio and proportion where:

real_image_width is to real_image_height as resized_image_width is to resized_image_height

First we need to get the real size of the image:

var img = new Image;
img.src = $('#imageButton').css('background-image').replace(/url\(|\)$/ig, "");
var imgW = img.width;
var imgH = img.height;

Then, compare which dimension is the largest and calculate the proportion:

var newW, newH;

if(imgW > imgH){
newW = $('#imageButton').width(); //100;
newH = imgH / imgW * newW;
}else{
newH = $('#imageButton').height(); //100
newW = imgW / imgH * newH;
}

console.log(newW+':'+newH);

If the image is not yet loaded or cached it will return a size of 0, a good way to fix this is to get the size when the image is has been loaded using .load() function.

Browsers also differ in sub-pixel rendering, I think you need to round off to nearest .5 decimal to get the exact safest value (43.7832 => 43.5). Using: (Math.round(value * 2) / 2).toFixed(1)

That's it! Here is the sample fiddle.



Related Topics



Leave a reply



Submit