javascript html image webp

javascript - Detectando soporte WebP



html image (11)

¿Cómo puedo detectar soporte para WebP a través de Javascript? Me gustaría utilizar la detección de características en lugar de la detección del navegador si es posible, pero no puedo encontrar la manera de hacerlo. Modernizr ( www.modernizr.com ) no lo verifica.


Aquí está el código sin tener que solicitar una imagen (tomada parcialmente de webpjs.appspot.com)

jsfiddle

function testWebP(callback) { var webP = new Image(); webP.src = ''data:image/webp;base64,UklGRjoAAABXRUJQVlA4IC4AAACyAgCdASoCAAIALmk0mk0iIiIiIgBoSygABc6WWgAA/veff/0PP8bA//LwYAAA''; webP.onload = webP.onerror = function () { callback(webP.height === 2); }; }; function notify(supported) { console.log((supported) ? "webP supported!" : "webP not supported."); } testWebP(notify);​


Creo que algo así podría funcionar:

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''; })();

En Firefox y IE, el manejador "onload" simplemente no se llamará si la imagen no puede ser entendida, y se llama "onerror" en su lugar.

No mencionaste jQuery, pero como ejemplo de cómo lidiar con la naturaleza asíncrona de esa verificación, puedes devolver un objeto 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(); }

Entonces podrías escribir:

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

Aquí hay un ejemplo jsfiddle.

Un comprobador más avanzado: http://jsfiddle.net/JMzj2/29/ . Éste carga imágenes de una URL de datos y verifica si se carga correctamente. Dado que WebP ahora también es compatible con imágenes sin pérdidas, puede verificar si el navegador actual solo admite WebP con pérdidas o WebP sin pérdidas. (Nota: Esto también verifica implícitamente el soporte de URL de datos).

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"); });


Esta es mi solución, toma alrededor de 6 ms y considero que WebP es solo una característica de un navegador moderno. Utiliza un enfoque diferente utilizando la función canvas.toDataUrl () en lugar de la imagen como la forma de detectar la característica:

function canUseWebP() { 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; } }


Esta es una vieja pregunta, pero Modernizr ahora es compatible con la detección de Webp.

http://modernizr.com/download/

Busque img-webp en img-webp no centrales.


Hay una manera de probar el soporte webP al instante . Es sincronizado y preciso, por lo que no hay necesidad de esperar una devolución de llamada para generar imágenes.

function testWebP = () => { const canvas = typeof document === ''object'' ? document.createElement(''canvas'') : {}; canvas.width = canvas.height = 1; return canvas.toDataURL ? canvas.toDataURL(''image/webp'').indexOf(''image/webp'') === 5 : false; }

Este método mejoró dramáticamente mi tiempo de renderizado


He encontrado que la detección de la función de soporte web necesita 300 ms cuando la página tiene JavaScript pesado. Así que escribí un script con funciones de almacenamiento en caché:

  • caché de script
  • caché localstorage

Solo detectará una vez cuando el usuario acceda primero a la página.

/** * @fileOverview WebP Support Detect. * @author ChenCheng<[email protected]> */ (function() { if (this.WebP) return; this.WebP = {}; WebP._cb = function(isSupport, _cb) { this.isSupport = function(cb) { cb(isSupport); }; _cb(isSupport); if (window.chrome || window.opera && window.localStorage) { window.localStorage.setItem("webpsupport", isSupport); } }; WebP.isSupport = function(cb) { if (!cb) return; if (!window.chrome && !window.opera) return WebP._cb(false, cb); if (window.localStorage && window.localStorage.getItem("webpsupport") !== null) { var val = window.localStorage.getItem("webpsupport"); WebP._cb(val === "true", cb); return; } var img = new Image(); img.src = "data:image/webp;base64,UklGRjoAAABXRUJQVlA4IC4AAACyAgCdASoCAAIALmk0mk0iIiIiIgBoSygABc6WWgAA/veff/0PP8bA//LwYAAA"; img.onload = img.onerror = function() { WebP._cb(img.width === 2 && img.height === 2, cb); }; }; WebP.run = function(cb) { this.isSupport(function(isSupport) { if (isSupport) cb(); }); }; })();


Solución preferida en HTML5

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

Wiki en W3C


Usando la respuesta de @ Pointy esto es para Angular 2+ :

import { Injectable } from ''@angular/core''; import { Subject } from ''rxjs/Subject''; @Injectable() export class ImageService { private isWebpEnabledSource = new Subject<boolean>(); isWebpEnabledAnnounced$ = this.isWebpEnabledSource.asObservable(); isWebpEnabled() { let webpImage = new Image(); webpImage.src = ''data:image/webp;base64,UklGRjIAAABXRUJQVlA4ICYAAACyAgCdASoCAAEALmk0mk0iIiIiIgBoSygABc6zbAAA/v56QAAAAA==''; webpImage.onload = () => { if (webpImage.width === 2 && webpImage.height === 1) { this.isWebpEnabledSource.next(true); } else { this.isWebpEnabledSource.next(false); } } } }



Imágenes de WebP con htaccess

Coloque lo siguiente en su archivo .htaccess y las imágenes jpg / png se reemplazarán con imágenes WebP si se encuentran en la misma carpeta.

<IfModule mod_rewrite.c> RewriteEngine On # Check if browser support WebP images RewriteCond %{HTTP_ACCEPT} image/webp # Check if WebP replacement image exists RewriteCond %{DOCUMENT_ROOT}/$1.webp -f # Serve WebP image instead RewriteRule (.+)/.(jpe?g|png)$ $1.webp [T=image/webp,E=accept:1] </IfModule> <IfModule mod_headers.c> Header append Vary Accept env=REDIRECT_accept </IfModule> <IfModule mod_mime.c> AddType image/webp .webp </IfModule>

Lea más here


La extensión Webp detecta y reemplaza JavaScript:

async function supportsWebp() { if (!self.createImageBitmap) return false; const webpData = ''data:image/webp;base64,UklGRh4AAABXRUJQVlA4TBEAAAAvAAAAAAfQ//73v/+BiOh/AAA=''; const blob = await fetch(webpData).then(r => r.blob()); return createImageBitmap(blob).then(() => true, () => false); } (async () => { if(await supportsWebp()) { console.log(''webp does support''); } else { $(''#banners .item'').each(function(){ var src=$(this).find(''img'').attr(''src''); src = src.replace(".webp", ".jpg"); $(this).find(''img'').attr(''src'',src); }); console.log(''webp does not support''); } })();