Upload WebP images [closed]

closed . This question needs details or to be clearer and is not currently accepting answers.

want to improve this question? Add details and make it clearer what problem is being solved by editing this post .

Closed 3 years ago .

improve this question

I would like to do something similar to what the following link does with the images of my site, using the webp format:

Example in this site

When I try to save the image by this link, by Chrome, it saves in webp format. If I try to save by another browser, it saves in jpg format. If I remove from the url the part after the"?", saves in jpg format in all browsers.

Does anyone know how this is done? If it's time to upload or display?

The site is made in PHP, using the Laravel framework.

Author: Julio Henrique, 2018-02-08

2 answers

This is done during the request. The code captures the parameter v (or the browser checks the request headers), checks if the image is in cache, if it is returned. In case it is not, you can do as follows.

On your server (I'll use Nginx for example)

# Aqui eu informo que toda imagem em `jpg` deverá ser redirecionada para o arquivo `image.jpg`
location ~ \.jpg$ {
    rewrite (.*) /image.php?$args last;
}

No PHP:

<?php

// Captura o nome da imagem que foi solicitada    
$request_uri = preg_replace("/^\/([^\?]*).*/", "$1", $_SERVER['REQUEST_URI']);

// Abre a imagem no formato JPG
$image = imagecreatefromjpeg($request_uri);

// Adiciona o Header informando o Content-Type
header("Content-Type: image/webp");

// Converte a imagem para WEBP
imagewebp($image);

This happens in Chrome as it captures the extension through the Content-Type.

Demonstration Of A Temporary 1
Demonstration Of A Temporary 2
Original Image

 1
Author: Valdeir Psr, 2018-02-08 19:42:52

This is done using Content negotiation using header Accept:, as I explained in this answer:

In Chrome, Opera and other Chromium-based browsers have support for webp so the header is passed like this by the browser when it requests the page:

GET /arquivos/ids/8043120-430-430/image-14d749d28e68b73ea65d4832318ba6d6.jpg?v=636408381268700000 HTTP/1.1
Host: shopfacil.vteximg.com.br
Connection: keep-alive
User-Agent: Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.119 Safari/537.36 OPR/51.0.2830.26
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8

But when you access via Firefox for not having webp support will be accessed via so probably see that that in Accept: has image/webp:

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,**image/webp**,image/apng,*/*;q=0.8

Already in Firefox the browser requests like this:

GET /arquivos/ids/8043120-430-430/image-14d749d28e68b73ea65d4832318ba6d6.jpg?v=636408381268700000 HTTP/1.1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: pt-BR,pt;q=0.8,en-US;q=0.5,en;q=0.3
Connection:keep-alive
Host: shopfacil.vteximg.com.br
User-Agent: Mozilla/5.0 (Windows NT 6.3; Win64; x64; rv:58.0) Gecko/20100101 Firefox/58.0

Of course in PHP there is nothing native to the q-factor , but there are libs via PEAR like

Or use the script of this response but adjust it to the header Accept: (which is used for mime-type), for example:

function AcceptHeader($name)
{
    $qvalues = array(); // used to store values

    if (empty($_SERVER[$name]) === false) {
        $result = preg_match_all('/([a-z]{1,8}(-[a-z]{1,8})?)\s*(;\s*q\s*=\s*(1|0\.[0-9]+))?/i', $_SERVER[$name], $parsed);

        if ($result && count($parsed[1])) {
            $qvalues = array_combine($parsed[1], $parsed[4]);

            // Define o valor para tipos sem q-value definido
            foreach ($qvalues as &$val) {
                if ($val === '') {
                     $val = 1;
                }
            }

            // sort list based on value 
            arsort($qvalues, SORT_NUMERIC);
        }
    }

    return $qvalues;
}

Example to get the Type header requested by browser:

$tipos = AcceptHeader('HTTP_ACCEPT');

Example for languages supported by the browser:

$idiomas = AcceptHeader('HTTP_ACCEPT_LANGUAGE');

But since the focus is mime-type, then it should use something like this:

$tipos = AcceptHeader('HTTP_ACCEPT');

//Filtra somente imagens
$tipos = array_filter($tipos, function($header, $qvalue) {
    return stripos($header, 'image/') === 0;
}, ARRAY_FILTER_USE_BOTH);

//Pega a primeira chave
$tipos = reset($tipos);
$tipo = key($tipos);

//Se contiver imagem/webp
if ($tipo == 'image/webp') {
     readfile('images/webp/image.webp');
} else {
     readfile('images/jpg/image.jpg');
}

Of course it can be much simpler still, this all above is just a suggestion of how to deliver according to the browser or user preference the type of content, but you can choose to decide only to check if there is support independent of the priority of q-factor using preg_match and regex , like this:

if (isset($_SERVER['HTTP_ACCEPT']) && preg_match('#[\s,;]image/webp[\s,;]#', $_SERVER['HTTP_ACCEPT'])) {
     readfile('images/webp/image.webp');
} else {
     readfile('images/jpg/image.jpg');
}
 0
Author: Guilherme Nascimento, 2018-02-11 21:48:21