检测 WebP 支持

IT技术 javascript html image webp
2021-02-04 20:51:11

如何通过 Javascript 检测对 WebP 的支持?如果可能,我想使用功能检测而不是浏览器检测,但我找不到这样做的方法。Modernizr ( www.modernizr.com ) 不检查它。

6个回答

这是我的解决方案 - 大约需要 6 毫秒,我认为 WebP 只是现代浏览器的一项功能。使用不同的方法使用 canvas.toDataUrl() 函数而不是图像作为检测特征的方法:

function support_format_webp()
{
 var elem = document.createElement('canvas');

 if (!!(elem.getContext && elem.getContext('2d')))
 {
  // was able or not to get WebP representation
  return elem.toDataURL('image/webp').indexOf('data:image/webp') == 0;
 }
 else
 {
  // very old browser like IE 8, canvas not supported
  return false;
 }
}
这应该是公认的答案,因为所有其他人都有延迟,因为指向网络资源或数据 URI
2021-03-25 20:51:11
这在支持显示 webp 的 Firefox 65 中不起作用,但不能从画布元素创建 webp 数据 url。
2021-04-02 20:51:11
,如果它的工作对FF65和Edge18是巨大的。它们都支持 webp,但使用“data:image/png”序列化画布
2021-04-12 20:51:11
简化版: webp = e => document.createElement('canvas').toDataURL('image/webp').indexOf('data:image/webp') == 0;
2021-04-13 20:51:11
喜欢这个,因为它是同步的,但是 @carlcheel 是正确的。FF 65(确实有 webp 支持)在这里仍然返回 false :-(
2021-04-13 20:51:11

我认为这样的事情可能会奏效:

var hasWebP = false;
(function() {
  var img = new Image();
  img.onload = function() {
    hasWebP = !!(img.height > 0 && img.width > 0);
  };
  img.onerror = function() {
    hasWebP = false;
  };
  img.src = 'http://www.gstatic.com/webp/gallery/1.webp';
})();

在 Firefox 和 IE 中,如果无法理解图像,则根本不会调用“onload”处理程序,而是调用“onerror”。

您没有提到 jQuery,但作为如何处理该检查的异步性质的示例,您可以返回一个 jQuery“Deferred”对象:

function hasWebP() {
  var rv = $.Deferred();
  var img = new Image();
  img.onload = function() { rv.resolve(); };
  img.onerror = function() { rv.reject(); };
  img.src = 'http://www.gstatic.com/webp/gallery/1.webp';
  return rv.promise();
}

然后你可以写:

hasWebP().then(function() {
  // ... code to take advantage of WebP ...
}, function() {
  // ... code to deal with the lack of WebP ...
});

这是一个 jsfiddle 示例。


更高级的检查器:http : //jsfiddle.net/JMzj2/29/这个从数据 URL 加载图像并检查它是否加载成功。由于 WebP 现在也支持无损图像,您可以检查当前浏览器是否仅支持有损 WebP 或也支持无损 WebP。(注意:这也隐式地检查数据 URL 支持。)

var hasWebP = (function() {
    // some small (2x1 px) test images for each feature
    var images = {
        basic: "data:image/webp;base64,UklGRjIAAABXRUJQVlA4ICYAAACyAgCdASoCAAEALmk0mk0iIiIiIgBoSygABc6zbAAA/v56QAAAAA==",
        lossless: "data:image/webp;base64,UklGRh4AAABXRUJQVlA4TBEAAAAvAQAAAAfQ//73v/+BiOh/AAA="
    };

    return function(feature) {
        var deferred = $.Deferred();

        $("<img>").on("load", function() {
            // the images should have these dimensions
            if(this.width === 2 && this.height === 1) {
                deferred.resolve();
            } else {
                deferred.reject();
            }
        }).on("error", function() {
            deferred.reject();
        }).attr("src", images[feature || "basic"]);

        return deferred.promise();
    }
})();

var add = function(msg) {
    $("<p>").text(msg).appendTo("#x");
};

hasWebP().then(function() {
    add("Basic WebP available");
}, function() {
    add("Basic WebP *not* available");
});

hasWebP("lossless").then(function() {
    add("Lossless WebP available");
}, function() {
    add("Lossless WebP *not* available");
});
好吧,我原来的答案只有“onload”——我什至不知道 Image 对象有“onerror”:-)
2021-03-14 20:51:11
哦,呸。我使用了 data: url 而不是图像,而 IE7 不支持。:P
2021-03-20 20:51:11
我刚刚意识到我可以让 IE8 与 data: urls 一起正常工作,并让 IE7 为它抛出错误;问题是他们不直接在 javascript 中支持它们。请参阅:jsfiddle.net/HaLXz
2021-03-26 20:51:11
它在 IE7 中对我有用 - 试试我刚刚链接到答案末尾的 jsFiddle。
2021-04-02 20:51:11
惊人的!这适用于 FF、Chrome 和 IE 9。出于某种原因,它不适用于 IE8 或 IE7。
2021-04-05 20:51:11

首选解决方案 HTML5

<picture>
  <source srcset="/path/to/image.webp" type="image/webp">
  <img src="/path/to/image.jpg" alt="insert alt text here">
</picture>

W3C 上的维基

所有支持 webp 的浏览器都支持图片元素吗?
2021-03-24 20:51:11
尽管原生 HTML5 更可取,但大多数浏览器同时加载 JPG 和 WEBP,这会对下载时间产生负面影响。深入:smashingmagazine.com/2013/05/...
2021-03-24 20:51:11
是的,这是问题的最佳解决方案。谢谢
2021-03-27 20:51:11
完美运行,这type="image/webp"对于浏览器在未知格式时跳过它至关重要!
2021-03-31 20:51:11
这很好,但它不适用于背景图像,并且如果您将 webp 改造为站点,并且需要修改 html,这也意味着修改 css 中引用 img 标签的所有位置。
2021-04-07 20:51:11

谷歌官方方式:

由于一些旧浏览器对 webp 部分支持,因此最好更具体地说明您尝试使用的 webp 功能并检测此特定功能,以下是Google关于如何检测特定 webp 功能的官方建议

// check_webp_feature:
//   'feature' can be one of 'lossy', 'lossless', 'alpha' or 'animation'.
//   'callback(feature, isSupported)' will be passed back the detection result (in an asynchronous way!)
function check_webp_feature(feature, callback) {
    var kTestImages = {
        lossy: "UklGRiIAAABXRUJQVlA4IBYAAAAwAQCdASoBAAEADsD+JaQAA3AAAAAA",
        lossless: "UklGRhoAAABXRUJQVlA4TA0AAAAvAAAAEAcQERGIiP4HAA==",
        alpha: "UklGRkoAAABXRUJQVlA4WAoAAAAQAAAAAAAAAAAAQUxQSAwAAAARBxAR/Q9ERP8DAABWUDggGAAAABQBAJ0BKgEAAQAAAP4AAA3AAP7mtQAAAA==",
        animation: "UklGRlIAAABXRUJQVlA4WAoAAAASAAAAAAAAAAAAQU5JTQYAAAD/////AABBTk1GJgAAAAAAAAAAAAAAAAAAAGQAAABWUDhMDQAAAC8AAAAQBxAREYiI/gcA"
    };
    var img = new Image();
    img.onload = function () {
        var result = (img.width > 0) && (img.height > 0);
        callback(feature, result);
    };
    img.onerror = function () {
        callback(feature, false);
    };
    img.src = "data:image/webp;base64," + kTestImages[feature];
}

示例用法:

check_webp_feature('lossy', function (feature, isSupported) {
    if (isSupported) {
        // webp is supported, 
        // you can cache the result here if you want
    }
});

请注意,图像加载是非阻塞和异步的这意味着任何依赖于 WebP 支持的代码都最好放在回调函数中。

另请注意,其他同步解决方案不适用于Firefox 65

这是一个老问题,但 Modernizr 现在支持 Webp 检测。

http://modernizr.com/download/

img-webp在非核心检测下查找

源代码有助于查看他们做了什么github.com/Modernizr/Modernizr/blob/...
2021-03-31 20:51:11
对我来说,它工作得非常可靠,它允许您使用 css 类 .webp 和 .no-webp 以获得更大的灵活性。
2021-03-31 20:51:11
不得不使用一些自定义检查而不是 Modernizr,因为我找不到如何让它在像 angular cli 这样的现代堆栈上工作的方法(即使使用 ngx-build-plus)
2021-04-11 20:51:11