获取背景图片的最终大小

10
有没有一种简单的方法使用Javascript或jQuery获取背景图像的最终高度和宽度,即使应用了background-size属性?我是说,我知道我可以获取背景图像的url并将其加载到Image对象中,然后获取其宽度和高度。但这是源图像的大小。如果有人使用CSS进行缩放,则大小会发生变化。我该如何找到其最终大小?@edit 这与标记为类似的问题不同,因为它没有说明如何获取像素大小,如果有人更改了background-size属性。

这对你有用吗? document.getElementById("myImage").style.offsetHeight; document.getElementById("myImage").style.offsetWidth; - Anupam Saini
这将返回元素的大小,而不是背景图像的大小,并且在样式中没有属性offsetHeightoffsetWidth。它们是高度和宽度。如果我没错的话,只有在之前通过CSS应用它们时才会返回它们。而offsetWidthoffsetHeight返回元素的大小,而不是背景图像的大小。 - Victor Ferreira
1
我所能想到的唯一方法是读取 $("img").css("background-size") 属性并进行解析。它只能是 cover // 元素宽度contain // 最大图像尺寸 或静态值 (px、em 或 %)。 - CodingIntrigue
我想我得计算一下。检查它是否为百分比并将百分比应用于元素大小,如果是包含或覆盖,请检查哪个维度较小或较大,并祈求它们,'rem'、'em'、'vh'等是否被应用(我不确定),将自动转换为像素(请注意,CSS 中的某些内容会被转换,例如,如果您使用 'em',至少 Chrome 会将其转换为像素)。 - Victor Ferreira
可能是重复的问题:如何在jQuery中获取背景图片大小? - davidcondrey
我已经阅读了它,但它并没有如预期地回答问题。它没有说明如果有人更改了background-size规则,如何获取以像素为单位的大小。 - Victor Ferreira
2个回答

17

使用getComputedStyle,我创建了这个脚本,它返回给定元素背景的宽度和高度(以像素为单位)。它适用于:

  • 将维度(宽度或高度)设置为auto,无论是明确设置还是因未给出特定值而默认为auto(宽度和高度都默认为auto
  • 将维度设置为百分比%
  • 将维度设置为像素px
  • 将维度设置为任何前述选项的组合。(例如:width: 100px; height: autowidth: auto; height: 32.4%height: 100px; width: 2%width: 21.2%
  • background-size设置为covercontain

如果使用外部CSS文件、内联CSS、内联标题CSS或根本未设置background-size(意味着宽度和高度都为auto),则它可以工作。

这里是一个包含“cover”示例的JsFiddle

http://jsfiddle.net/gp4e9d3z/3/

这里是StackOverflow的代码片段(带有百分比auto单位)

function getBackgroundSize(elem) {
    // This:
    //       * Gets elem computed styles:
    //             - CSS background-size
    //             - element's width and height
    //       * Extracts background URL
    var computedStyle = getComputedStyle(elem),
        image = new Image(),
        src = computedStyle.backgroundImage.replace(/url\((['"])?(.*?)\1\)/gi, '$2'),
        cssSize = computedStyle.backgroundSize,
        elemW = parseInt(computedStyle.width.replace('px', ''), 10),
        elemH = parseInt(computedStyle.height.replace('px', ''), 10),
        elemDim = [elemW, elemH],
        computedDim = [],
        ratio;
    // Load the image with the extracted URL.
    // Should be in cache already.
    image.src = src;
    // Determine the 'ratio'
    ratio = image.width > image.height ? image.width / image.height : image.height / image.width;
    // Split background-size properties into array
    cssSize = cssSize.split(' ');
    // First property is width. It is always set to something.
    computedDim[0] = cssSize[0];
    // If height not set, set it to auto
    computedDim[1] = cssSize.length > 1 ? cssSize[1] : 'auto';
    if(cssSize[0] === 'cover') {
        // Width is greater than height
        if(elemDim[0] > elemDim[1]) {
            // Elem's ratio greater than or equal to img ratio
            if(elemDim[0] / elemDim[1] >= ratio) {
                computedDim[0] = elemDim[0];
                computedDim[1] = 'auto';
            } else {
                computedDim[0] = 'auto';
                computedDim[1] = elemDim[1];
            }
        } else {
            computedDim[0] = 'auto';
            computedDim[1] = elemDim[1];
        }
    } else if(cssSize[0] === 'contain') {
        // Width is less than height
        if(elemDim[0] < elemDim[1]) {
            computedDim[0] = elemDim[0];
            computedDim[1] = 'auto';
        } else {
            // elem's ratio is greater than or equal to img ratio
            if(elemDim[0] / elemDim[1] >= ratio) {
                computedDim[0] = 'auto';
                computedDim[1] = elemDim[1];
            } else {
                computedDim[1] = 'auto';
                computedDim[0] = elemDim[0];
            }
        }
    } else {
        // If not 'cover' or 'contain', loop through the values
        for(var i = cssSize.length; i--;) {
            // Check if values are in pixels or in percentage
            if (cssSize[i].indexOf('px') > -1) {
                // If in pixels, just remove the 'px' to get the value
                computedDim[i] = cssSize[i].replace('px', '');
            } else if (cssSize[i].indexOf('%') > -1) {
                // If percentage, get percentage of elem's dimension
                // and assign it to the computed dimension
                computedDim[i] = elemDim[i] * (cssSize[i].replace('%', '') / 100);
            }
        }
    }
    // If both values are set to auto, return image's 
    // original width and height
    if(computedDim[0] === 'auto' && computedDim[1] === 'auto') {
        computedDim[0] = image.width;
        computedDim[1] = image.height;
    } else {
        // Depending on whether width or height is auto,
        // calculate the value in pixels of auto.
        // ratio in here is just getting proportions.
        ratio = computedDim[0] === 'auto' ? image.height / computedDim[1] : image.width / computedDim[0];
        computedDim[0] = computedDim[0] === 'auto' ? image.width / ratio : computedDim[0];
        computedDim[1] = computedDim[1] === 'auto' ? image.height / ratio : computedDim[1];
    }
    // Finally, return an object with the width and height of the
    // background image.
    return {
        width: computedDim[0],
        height: computedDim[1]
    };
}

// Stuff for debugging

function updateData() {
    var background = getBackgroundSize(document.body);
    document.getElementById('width').innerHTML = background.width + 'px';
    document.getElementById('height').innerHTML = background.height + 'px';
    document.getElementById('winWidth').innerHTML = getComputedStyle(document.body).width;
    document.getElementById('winHeight').innerHTML = getComputedStyle(document.body).height;
}
// Execute onload, so that the background image is already loaded.
window.onload = window.onresize = updateData;
html, body {
    width: 100%;
    height: 100%;
    margin: 0;
    padding: 0;
}
body {
    background: url('http://hdwallpapersfit.com/wp-content/uploads/2015/03/images-7.jpg');
    background-size: 80% auto;
}
div {
    background: rgba(0, 0, 0, 0.5);
    color: #fff;
}
<div id="data">
    Background width: <span id="width"></span>
    <br>
    Background height: <span id="height"></span>
    <hr>
    Body width: <span id="winWidth"></span>
    <br>
    Body height: <span id="winHeight"></span>
</div>


必须给你一个加一,因为你的数量和细节非常出色。 - aintnorest
没话可说。完美。 - Long Nguyen

1

使用JSFiddle 这里,我发现更改容器的高度或宽度会强制将图像缩放到最大高度或宽度。这意味着背景的一个边缘的测量值将等于容器的一个维度。利用这一点和一些比例,我们可以计算出图像的尺寸。

// let .container  represent element containing the image
var image; // the image object to the background image
var dim_h, dim_w; // the height and width of the actual image


height = $(".container").height();
width = $(".container").width();

if (height >= width)
{
  dim_h = height;
  dim_w = (height / image.height) * image.width;
}
else
{
  dim_w = width;
  dim_h = (width / image.width) * image.height;
}

// dim_w and dim_h contain the width and height of the actual 
// background image after scaling

上述代码使用下面的比例来计算它。
(element_height / image_height) == (element_width / image_width)

我认为它应该能给你想要的答案。


我想要背景图片。 - Victor Ferreira
背景图片的大小不应该是它所包含元素的大小吗? - Zara Kay
如果我使用background-size: cover,会改变背景图片的大小吗? - Victor Ferreira
根据w3c网站此处的说明。据我所知,如果使用cover,则背景将被缩放以适应元素的背景区域,因此它应该等于包含它的元素的大小。 - Zara Kay
将背景图像缩放到尽可能大,以使背景区域完全被背景图像覆盖。背景图像的某些部分可能不在背景定位区域内可见,因此不可见的部分在框外,因此它比框大,因此大小不同。 - Victor Ferreira
1
@MigaraLiyanagamage 不是相关的,但要小心,w3school不是w3c。 - Kaiido

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接