如何从srcset确定最高分辨率的图像

时间:2016-04-11 07:01:16

标签: javascript jquery image url srcset

说我的图像为

<img srcset="large.jpg 1400w, medium.jpg 700w, small.jpg 400w"
     sizes="(min-width: 700px) 700px, 100vw"
     alt="A woman reading">


现在,这也可以采用类似

的格式
<img srcset="large.jpg 2x, medium.jpg 1.3x, small.jpg 0.8x"
     sizes="(min-width: 700px) 700px, 100vw"
     alt="A woman reading">


此外,(不是有效的HTML)

<img srcset="large.jpg 1400w, medium.jpg 1.3x, small.jpg 0.8x"
     sizes="(min-width: 700px) 700px, 100vw"
     alt="A woman reading">

<击>
现在我如何提取具有最高分辨率图像的URL 我想过分割srcset然后提取大小,但问题是大小可能是1200w格式或2x格式或两者都有,我不知道如何区分这是1200w格式还是2x格式,即使我确定了什么,我如何比较它们以确定最大尺寸。

我希望我可以展示我曾经尝试过的东西但是我没有想到如何做到这一点!

3 个答案:

答案 0 :(得分:2)

首先,您的HTML代码无效,因为您无法将xw描述符混合为srcset。选择一个但不是两个。

1)除非您全部下载,否则您无法知道哪个图片更大,当然您可以 - 当受支持的服务器端 - 对每个图片执行HEAD请求时并检查Content-Length标题属性。它并不容易,你得到的只是图像大小,以字节为单位,而不是它的尺寸,但它是一个很好的近似。大概是这样的:

var sizes = [];

// Peform this for each UR...
$.ajax({
    type: "HEAD",
    url: imageUrl,
    success: function(data, textStatus, request) {
        sizes.push({
            url: imageUrl,
            size: parseInt(request.getResponseHeader("Content-Length"));
        });
    }
});

您可以通过简单地拆分srcset属性并忽略大小部分来获取网址(我确信对正则表达式有更好了解的人可以做得更好):

var urls = srcset.replace(/\s+[0-9]+(\.[0-9]+)?[wx]/g, "").split(/,/); 

呼叫可以并行完成,或者 - 更容易IMO - 使用队列和$(document).queue() jQuery方法顺序完成。

这无法始终完成(可能是因为服务器不接受HEAD或图片大小因压缩和/或宽高比而过于相似)然后您必须解析 srcset属性。

2)让我们首先看一下概念验证(读作:它不完整也不高效)你可以做些什么像素密度描述符x:用空白.split(/ /)分割,然后选择最大的空格。

// Read value from tag...this is just for testing
var srcset = "small.jpg 0.8x, large.jpg 1.5x, medium.jpg 1.3x";

var biggestImage = "";
var highestPixelDensity = 1;

for (var descriptor of srcset.split(/,/)) {
    var parts = descriptor.trim().split(/ /);

    // Here we check only for pixel density, see later for
    // width descriptor but code is straightforward
    var pixelDensity = parseFloat(parts[1].substring(-1));
    if (pixelDensity > highestPixelDensity) {
        biggestImage = parts[0];
        highestPixelDensity = pixelDensity;
    }
}

宽度描述符w的情况有所不同,因为它与sizes有关,那么您首先需要确定应用了哪一个。它有点复杂,但使用window.matchMedia()很容易(同样,它不是完整的代码,而是一个说明性的概念证明):

// Read this from tag...
var sizes = "(min-width: 800px) 700px, (min-width: 700px) 300px";

for (var descriptor of sizes.split(/,/)) {
    // Love this from https://stackoverflow.com/a/651646/1207195
    var imageSize = descriptor.split(/[, ]+/).pop();

    // You still need to handle last item special case (where there is not media query).
    var mediaQuery = descriptor.substring(-imageSize.length);

    // You can stop with first matched media query, you have your required imageSize
    var isMatch = window.matchMedia(mediaQuery).matches;
}

现在您已经需要大小(检查其单位并进行适当转换,例如this post),并且您已经完成了从srcset中提取的宽度描述符使用它。

请注意,除非您下载,否则您不知道哪个图片更大。您可以假设更高的像素密度x或更高的宽度描述符w(但必须sizes属性内容相关计算,更大的屏幕使用更大的图像)会给你更大的一个。当然,这是一个假设,然后在某些情况下可能会失败。要确定必须使用哪一个,只需:

var isPixelDensity = srcset.trim().substr(-1) === "x";

只是......把这些样本放在一起,处理丢失的角落案例,基本的错误处理和浏览器特定的问题,你就完成了......

答案 1 :(得分:1)

这是我用的:

 static getHighestResImg(element){
        if(element.getAttribute('srcset')){
            let highResImgUrl = '';
            let maxRes = 0;
            let imgWidth,urlWidthArr;
            element.getAttribute('srcset').split(',').forEach((item)=>{
                urlWidthArr = item.trim().split(' ');
                imgWidth = parseInt(urlWidthArr[1]);
                if(imgWidth > maxRes) {
                    maxRes = imgWidth;
                    highResImgUrl = urlWidthArr[0];
                }

            });

            return highResImgUrl;
        }else{
          return  element.getAttribute('src');
        }

    }

答案 2 :(得分:0)

我需要对生成的wordpress图像和相关的srcset

执行相同的操作

Wordpress创建srcset的方式是首先显示较小的图像然后继续增加,直到它获得srcset中的最大图像。

wordpress生成的示例代码:

<img width="300" height="221" src="http://www.example.com/wp-content/uploads/2017/01/Sharon-Ron-Chip-300x221.jpg" class="vc_single_image-img attachment-medium" alt="" srcset="http://www.example.com/wp-content/uploads/2017/01/Sharon-Ron-Chip-300x221.jpg 300w, http://www.example.com/wp-content/uploads/2017/01/Sharon-Ron-Chip-768x566.jpg 768w, http://www.example.com/wp-content/uploads/2017/01/Sharon-Ron-Chip-1024x755.jpg 1024w" sizes="(max-width: 300px) 100vw, 300px">

另外,在某些情况下,当图片太小时,wordpress根本不会创建srcset属性。

所以,这就是我所做的:(在代码中更改my_image_class_to_target到您需要的目标类)

jQuery('img.my_image_class_to_target').each(function () {
    var mysrcset = jQuery(this).attr('srcset');
    if (typeof mysrcset !== 'undefined'){ //checking if the srcset attribute is defined
        lastsrcset = mysrcset.split(',');
        lastsrc = lastsrcset[(lastsrcset.length - 1)];
        lastpuresrc = lastsrc.split(' ');
        mysrc = lastpuresrc[1];

    } else { //when srcset is not defined in case of small images
    var mysrcset = jQuery(this).attr('src');
        mysrc = mysrcset;
    }

    // display or use src of biggest image src
    console.log(mysrc);

});

我是Javascript / jQuery的新手,所以请原谅我是否采取了更长的路线。 ;)

欢迎对代码进行任何添加/更新。