Upload webp images

Asked

Viewed 496 times

0

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

example on this site

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

Does anyone know how this is done? Whether it’s time to upload or view?

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

  • your image.jpg? v=123 What is the problem?

2 answers

1

This is done during the request. The code captures the parameter v (Or the browser checks the request headers), checks whether the image is in cache, if it is returns. If it is not, you can do it as follows.

On your server (I’m gonna use the 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;
}

In 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 the Chrome, because it captures the extension through the Content-Type.

Temporary Demonstration 1
Temporary Demonstration 2
Original Image

  • I understand Valdeir, thank you very much. I will try to do here.

0

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

In Chrome, Opera and other Chromium-based browsers have support for webp so the header is passed like this by the browser when ordering 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 accessing via Firefox for not having webp support will be accessed via so probably, see that on Accept: has image/webp:

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

Already in the Firefox browser so requests:

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 as

Or use the script of this answer 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 catch type header requested by browser:

$tipos = AcceptHeader('HTTP_ACCEPT');

Example for obtaining browser-supported languages:

$idiomas = AcceptHeader('HTTP_ACCEPT_LANGUAGE');

But since the focus is mime-type, then you should use more or less 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, all this above is just a suggestion of how to deliver as preferred by the browser or user the type of content, but you can choose to just decide to check if there is support independent of the priority of q-factor using preg_match and regex, thus:

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

Browser other questions tagged

You are not signed in. Login or sign up in order to post.