mirror of
https://github.com/Piwigo/Piwigo.git
synced 2026-06-02 04:15:05 +02:00
issue #223 support for WebP
* after PR#1785 we needed some more changes * support for animated webP
This commit is contained in:
@@ -212,6 +212,60 @@ class pwg_image
|
||||
return $result;
|
||||
}
|
||||
|
||||
static function webp_info($source_filepath)
|
||||
{
|
||||
// function based on https://stackoverflow.com/questions/61221874/detect-if-a-webp-image-is-transparent-in-php
|
||||
//
|
||||
// https://github.com/webmproject/libwebp/blob/master/src/dec/webp_dec.c
|
||||
// https://developers.google.com/speed/webp/docs/riff_container
|
||||
// https://developers.google.com/speed/webp/docs/webp_lossless_bitstream_specification
|
||||
// https://stackoverflow.com/questions/61221874/detect-if-a-webp-image-is-transparent-in-php
|
||||
|
||||
$fp = fopen($source_filepath, 'rb');
|
||||
if (!$fp) {
|
||||
throw new Exception("webp_info(): fopen($f): Failed");
|
||||
}
|
||||
$buf = fread($fp, 25);
|
||||
fclose($fp);
|
||||
|
||||
switch (true) {
|
||||
case!is_string($buf):
|
||||
case strlen($buf) < 25:
|
||||
case substr($buf, 0, 4) != 'RIFF':
|
||||
case substr($buf, 8, 4) != 'WEBP':
|
||||
case substr($buf, 12, 3) != 'VP8':
|
||||
throw new Exception("webp_info(): not a valid webp image");
|
||||
|
||||
case $buf[15] == ' ':
|
||||
// Simple File Format (Lossy)
|
||||
return array(
|
||||
'type' => 'VP8',
|
||||
'has-animation' => false,
|
||||
'has-transparent' => false,
|
||||
);
|
||||
|
||||
|
||||
case $buf[15] == 'L':
|
||||
// Simple File Format (Lossless)
|
||||
return array(
|
||||
'type' => 'VP8L',
|
||||
'has-animation' => false,
|
||||
'has-transparent' => (bool) (!!(ord($buf[24]) & 0x00000010)),
|
||||
);
|
||||
|
||||
case $buf[15] == 'X':
|
||||
// Extended File Format
|
||||
return array(
|
||||
'type' => 'VP8X',
|
||||
'has-animation' => (bool) (!!(ord($buf[20]) & 0x00000002)),
|
||||
'has-transparent' => (bool) (!!(ord($buf[20]) & 0x00000010)),
|
||||
);
|
||||
|
||||
default:
|
||||
throw new Exception("webp_info(): could not detect webp type");
|
||||
}
|
||||
}
|
||||
|
||||
static function get_rotation_angle($source_filepath)
|
||||
{
|
||||
list($width, $height, $type) = getimagesize($source_filepath);
|
||||
@@ -491,6 +545,7 @@ class image_ext_imagick implements imageInterface
|
||||
var $source_filepath = '';
|
||||
var $width = '';
|
||||
var $height = '';
|
||||
var $is_animated_webp = false;
|
||||
var $commands = array();
|
||||
|
||||
function __construct($source_filepath)
|
||||
@@ -504,6 +559,23 @@ class image_ext_imagick implements imageInterface
|
||||
@putenv('MAGICK_THREAD_LIMIT=1');
|
||||
}
|
||||
|
||||
if ('webp' == strtolower(get_extension($source_filepath)))
|
||||
{
|
||||
$webp_info = pwg_image::webp_info($source_filepath);
|
||||
|
||||
if ($webp_info['has-animation'])
|
||||
{
|
||||
$this->is_animated_webp = true;
|
||||
|
||||
// ImageMagick "identify" returns the list of width x height for each
|
||||
// frame, such as "400x300400x300400x300" (3 frames of 400x300), as a big
|
||||
// string, impossible to parse :-/ So let's use the PHP embedded function
|
||||
// getimagesize here.
|
||||
list($this->width, $this->height) = getimagesize($source_filepath);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
$command = $this->imagickdir.'identify -format "%wx%h" "'.realpath($source_filepath).'"';
|
||||
@exec($command, $returnarray);
|
||||
if(!is_array($returnarray) or empty($returnarray[0]) or !preg_match('/^(\d+)x(\d+)$/', $returnarray[0], $match))
|
||||
@@ -535,7 +607,8 @@ class image_ext_imagick implements imageInterface
|
||||
$this->width = $width;
|
||||
$this->height = $height;
|
||||
|
||||
$this->add_command('crop', $width.'x'.$height.'+'.$x.'+'.$y);
|
||||
// the final "!" is added to crop the canva too, for animated picture (with WebP in mind)
|
||||
$this->add_command('crop', $width.'x'.$height.'+'.$x.'+'.$y.'!');
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -565,6 +638,14 @@ class image_ext_imagick implements imageInterface
|
||||
|
||||
function set_compression_quality($quality)
|
||||
{
|
||||
if ($this->is_animated_webp)
|
||||
{
|
||||
// in cas of animated WebP, we need to maximize quality to 70 to avoid
|
||||
// heavy thumbnails (or square or whatever is displayed on the thumbnails
|
||||
// page)
|
||||
$quality = min($quality, 70);
|
||||
}
|
||||
|
||||
$this->add_command('quality', $quality);
|
||||
return true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user