mirror of
https://github.com/gosticks/wordpress-develop.git
synced 2026-06-28 22:30:04 +00:00
Images: enable WebP support.
Add support for uploading, editing and saving WebP images when supported by the server. Add 'image/webp' to supported mime types. Correctly identify WebP images and sizes even when PHP doesn't support WebP. Resize uploaded WebP files (when supported) and use for front end markup. Props markoheijne, blobfolio, Clorith, joemcgill, atjn, desrosj, spacedmonkey, marylauc, mikeschroder, hellofromtonya, flixos90. Fixes #35725. git-svn-id: https://develop.svn.wordpress.org/trunk@50810 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
@@ -306,6 +306,12 @@ function wp_stream_image( $image, $mime_type, $attachment_id ) {
|
||||
case 'image/gif':
|
||||
header( 'Content-Type: image/gif' );
|
||||
return imagegif( $image );
|
||||
case 'image/webp':
|
||||
if ( function_exists( 'imagewebp' ) ) {
|
||||
header( 'Content-Type: image/webp' );
|
||||
return imagewebp( $image, null, 90 );
|
||||
}
|
||||
return false;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
@@ -391,6 +397,11 @@ function wp_save_image_file( $filename, $image, $mime_type, $post_id ) {
|
||||
return imagepng( $image, $filename );
|
||||
case 'image/gif':
|
||||
return imagegif( $image, $filename );
|
||||
case 'image/webp':
|
||||
if ( function_exists( 'imagewebp' ) ) {
|
||||
return imagewebp( $image, $filename );
|
||||
}
|
||||
return false;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -517,6 +517,9 @@ function wp_generate_attachment_metadata( $attachment_id, $file ) {
|
||||
case 'image/png':
|
||||
$ext = '.png';
|
||||
break;
|
||||
case 'image/webp':
|
||||
$ext = '.webp';
|
||||
break;
|
||||
}
|
||||
$basename = str_replace( '.', '-', wp_basename( $file ) ) . '-image' . $ext;
|
||||
$uploaded = wp_upload_bits( $basename, '', $metadata['image']['data'] );
|
||||
@@ -913,7 +916,7 @@ function file_is_valid_image( $path ) {
|
||||
* @return bool True if suitable, false if not suitable.
|
||||
*/
|
||||
function file_is_displayable_image( $path ) {
|
||||
$displayable_image_types = array( IMAGETYPE_GIF, IMAGETYPE_JPEG, IMAGETYPE_PNG, IMAGETYPE_BMP, IMAGETYPE_ICO );
|
||||
$displayable_image_types = array( IMAGETYPE_GIF, IMAGETYPE_JPEG, IMAGETYPE_PNG, IMAGETYPE_BMP, IMAGETYPE_ICO, IMAGETYPE_WEBP ); // phpcs:ignore PHPCompatibility.Constants.NewConstants.imagetype_webpFound
|
||||
|
||||
$info = wp_getimagesize( $path );
|
||||
if ( empty( $info ) ) {
|
||||
@@ -963,6 +966,12 @@ function load_image_to_edit( $attachment_id, $mime_type, $size = 'full' ) {
|
||||
case 'image/gif':
|
||||
$image = imagecreatefromgif( $filepath );
|
||||
break;
|
||||
case 'image/webp':
|
||||
$image = false;
|
||||
if ( function_exists( 'imagecreatefromwebp' ) ) {
|
||||
$image = imagecreatefromwebp( $filepath );
|
||||
}
|
||||
break;
|
||||
default:
|
||||
$image = false;
|
||||
break;
|
||||
|
||||
@@ -993,7 +993,7 @@ function wp_media_upload_handler() {
|
||||
function media_sideload_image( $file, $post_id = 0, $desc = null, $return = 'html' ) {
|
||||
if ( ! empty( $file ) ) {
|
||||
|
||||
$allowed_extensions = array( 'jpg', 'jpeg', 'jpe', 'png', 'gif' );
|
||||
$allowed_extensions = array( 'jpg', 'jpeg', 'jpe', 'png', 'gif', 'webp' );
|
||||
|
||||
/**
|
||||
* Filters the list of allowed file extensions when sideloading an image from a URL.
|
||||
|
||||
@@ -1215,6 +1215,7 @@ We hope you enjoy your new site. Thanks!
|
||||
'jpeg',
|
||||
'png',
|
||||
'gif',
|
||||
'webp',
|
||||
// Video.
|
||||
'mov',
|
||||
'avi',
|
||||
|
||||
@@ -69,6 +69,8 @@ class WP_Image_Editor_GD extends WP_Image_Editor {
|
||||
return ( $image_types & IMG_PNG ) != 0;
|
||||
case 'image/gif':
|
||||
return ( $image_types & IMG_GIF ) != 0;
|
||||
case 'image/webp':
|
||||
return ( $image_types & IMG_WEBP ) != 0; // phpcs:ignore PHPCompatibility.Constants.NewConstants.img_webpFound
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -99,7 +101,15 @@ class WP_Image_Editor_GD extends WP_Image_Editor {
|
||||
return new WP_Error( 'error_loading_image', __( 'File doesn’t exist?' ), $this->file );
|
||||
}
|
||||
|
||||
$this->image = @imagecreatefromstring( $file_contents );
|
||||
// WebP may not work with imagecreatefromstring().
|
||||
if (
|
||||
function_exists( 'imagecreatefromwebp' ) &&
|
||||
( 'image/webp' === wp_get_image_mime( $this->file ) )
|
||||
) {
|
||||
$this->image = @imagecreatefromwebp( $this->file );
|
||||
} else {
|
||||
$this->image = @imagecreatefromstring( $file_contents );
|
||||
}
|
||||
|
||||
if ( ! is_gd_image( $this->image ) ) {
|
||||
return new WP_Error( 'invalid_image', __( 'File is not an image.' ), $this->file );
|
||||
@@ -459,6 +469,10 @@ class WP_Image_Editor_GD extends WP_Image_Editor {
|
||||
if ( ! $this->make_image( $filename, 'imagejpeg', array( $image, $filename, $this->get_quality() ) ) ) {
|
||||
return new WP_Error( 'image_save_error', __( 'Image Editor Save Failed' ) );
|
||||
}
|
||||
} elseif ( 'image/webp' == $mime_type ) {
|
||||
if ( ! function_exists( 'imagewebp' ) || ! $this->make_image( $filename, 'imagewebp', array( $image, $filename, $this->get_quality() ) ) ) {
|
||||
return new WP_Error( 'image_save_error', __( 'Image Editor Save Failed' ) );
|
||||
}
|
||||
} else {
|
||||
return new WP_Error( 'image_save_error', __( 'Image Editor Save Failed' ) );
|
||||
}
|
||||
@@ -502,6 +516,12 @@ class WP_Image_Editor_GD extends WP_Image_Editor {
|
||||
case 'image/gif':
|
||||
header( 'Content-Type: image/gif' );
|
||||
return imagegif( $this->image );
|
||||
case 'image/webp':
|
||||
if ( function_exists( 'imagewebp' ) ) {
|
||||
header( 'Content-Type: image/webp' );
|
||||
return imagewebp( $this->image, null, $this->get_quality() );
|
||||
}
|
||||
// Fall back to the default if webp isn't supported.
|
||||
default:
|
||||
header( 'Content-Type: image/jpeg' );
|
||||
return imagejpeg( $this->image, null, $this->get_quality() );
|
||||
|
||||
@@ -197,19 +197,30 @@ class WP_Image_Editor_Imagick extends WP_Image_Editor {
|
||||
}
|
||||
|
||||
try {
|
||||
if ( 'image/jpeg' === $this->mime_type ) {
|
||||
$this->image->setImageCompressionQuality( $quality );
|
||||
$this->image->setImageCompression( imagick::COMPRESSION_JPEG );
|
||||
} else {
|
||||
$this->image->setImageCompressionQuality( $quality );
|
||||
switch ( $this->mime_type ) {
|
||||
case 'image/jpeg':
|
||||
$this->image->setImageCompressionQuality( $quality );
|
||||
$this->image->setImageCompression( imagick::COMPRESSION_JPEG );
|
||||
break;
|
||||
case 'image/webp':
|
||||
if ( _wp_webp_is_lossy( $this->file ) ) {
|
||||
$this->image->setImageCompressionQuality( $quality );
|
||||
} else {
|
||||
// Use WebP lossless settings.
|
||||
$this->image->setImageCompressionQuality( 100 );
|
||||
$this->image->setOption( 'webp:lossless', 'true' );
|
||||
}
|
||||
break;
|
||||
default:
|
||||
$this->image->setImageCompressionQuality( $quality );
|
||||
}
|
||||
} catch ( Exception $e ) {
|
||||
return new WP_Error( 'image_quality_error', $e->getMessage() );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets or updates current image size.
|
||||
*
|
||||
|
||||
@@ -1141,7 +1141,7 @@ final class WP_Theme implements ArrayAccess {
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach ( array( 'png', 'gif', 'jpg', 'jpeg' ) as $ext ) {
|
||||
foreach ( array( 'png', 'gif', 'jpg', 'jpeg', 'webp' ) as $ext ) {
|
||||
if ( file_exists( $this->get_stylesheet_directory() . "/screenshot.$ext" ) ) {
|
||||
$this->cache_add( 'screenshot', 'screenshot.' . $ext );
|
||||
if ( 'relative' === $uri ) {
|
||||
|
||||
@@ -370,3 +370,11 @@ if ( ! function_exists( 'is_iterable' ) ) {
|
||||
return ( is_array( $var ) || $var instanceof Traversable );
|
||||
}
|
||||
}
|
||||
|
||||
// WebP constants may not be defined, even in cases where the format is supported.
|
||||
if ( ! defined( 'IMAGETYPE_WEBP' ) ) {
|
||||
define( 'IMAGETYPE_WEBP', 18 );
|
||||
}
|
||||
if ( ! defined( 'IMG_WEBP' ) ) {
|
||||
define( 'IMG_WEBP', IMAGETYPE_WEBP ); // phpcs:ignore PHPCompatibility.Constants.NewConstants.imagetype_webpFound
|
||||
}
|
||||
|
||||
@@ -91,7 +91,7 @@ class WP_Customize_Media_Control extends WP_Customize_Control {
|
||||
// Fake an attachment model - needs all fields used by template.
|
||||
// Note that the default value must be a URL, NOT an attachment ID.
|
||||
$ext = substr( $this->setting->default, -3 );
|
||||
$type = in_array( $ext, array( 'jpg', 'png', 'gif', 'bmp' ), true ) ? 'image' : 'document';
|
||||
$type = in_array( $ext, array( 'jpg', 'png', 'gif', 'bmp', 'webp' ), true ) ? 'image' : 'document';
|
||||
|
||||
$default_attachment = array(
|
||||
'id' => 1,
|
||||
|
||||
@@ -3340,6 +3340,8 @@ function gd_edit_image_support($mime_type) {
|
||||
return (imagetypes() & IMG_PNG) != 0;
|
||||
case 'image/gif':
|
||||
return (imagetypes() & IMG_GIF) != 0;
|
||||
case 'image/webp':
|
||||
return (imagetypes() & IMG_WEBP) != 0; // phpcs:ignore PHPCompatibility.Constants.NewConstants.img_webpFound
|
||||
}
|
||||
} else {
|
||||
switch( $mime_type ) {
|
||||
@@ -3349,6 +3351,8 @@ function gd_edit_image_support($mime_type) {
|
||||
return function_exists('imagecreatefrompng');
|
||||
case 'image/gif':
|
||||
return function_exists('imagecreatefromgif');
|
||||
case 'image/webp':
|
||||
return function_exists('imagecreatefromwebp');
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -3318,7 +3318,7 @@ function translate_smiley( $matches ) {
|
||||
|
||||
$matches = array();
|
||||
$ext = preg_match( '/\.([^.]+)$/', $img, $matches ) ? strtolower( $matches[1] ) : false;
|
||||
$image_exts = array( 'jpg', 'jpeg', 'jpe', 'gif', 'png' );
|
||||
$image_exts = array( 'jpg', 'jpeg', 'jpe', 'gif', 'png', 'webp' );
|
||||
|
||||
// Don't convert smilies that aren't images - they're probably emoji.
|
||||
if ( ! in_array( $ext, $image_exts, true ) ) {
|
||||
|
||||
@@ -2886,6 +2886,7 @@ function wp_check_filetype_and_ext( $file, $filename, $mimes = null ) {
|
||||
'image/gif' => 'gif',
|
||||
'image/bmp' => 'bmp',
|
||||
'image/tiff' => 'tif',
|
||||
'image/webp' => 'webp',
|
||||
)
|
||||
);
|
||||
|
||||
@@ -3063,6 +3064,35 @@ function wp_get_image_mime( $file ) {
|
||||
} else {
|
||||
$mime = false;
|
||||
}
|
||||
|
||||
if ( false !== $mime ) {
|
||||
return $mime;
|
||||
}
|
||||
|
||||
$handle = fopen( $file, 'rb' );
|
||||
if ( false === $handle ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$magic = fread( $handle, 12 );
|
||||
if ( false === $magic ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Add WebP fallback detection when image library doesn't support WebP.
|
||||
// Note: detection values come from LibWebP, see
|
||||
// https://github.com/webmproject/libwebp/blob/master/imageio/image_dec.c#L30
|
||||
$magic = bin2hex( $magic );
|
||||
if (
|
||||
// RIFF.
|
||||
( 0 === strpos( $magic, '52494646' ) ) &&
|
||||
// WEBP.
|
||||
( 16 === strpos( $magic, '57454250' ) )
|
||||
) {
|
||||
$mime = 'image/webp';
|
||||
}
|
||||
|
||||
fclose( $handle );
|
||||
} catch ( Exception $e ) {
|
||||
$mime = false;
|
||||
}
|
||||
@@ -3101,6 +3131,7 @@ function wp_get_mime_types() {
|
||||
'png' => 'image/png',
|
||||
'bmp' => 'image/bmp',
|
||||
'tiff|tif' => 'image/tiff',
|
||||
'webp' => 'image/webp',
|
||||
'ico' => 'image/x-icon',
|
||||
'heic' => 'image/heic',
|
||||
// Video formats.
|
||||
@@ -3222,7 +3253,7 @@ function wp_get_ext_types() {
|
||||
return apply_filters(
|
||||
'ext2type',
|
||||
array(
|
||||
'image' => array( 'jpg', 'jpeg', 'jpe', 'gif', 'png', 'bmp', 'tif', 'tiff', 'ico', 'heic' ),
|
||||
'image' => array( 'jpg', 'jpeg', 'jpe', 'gif', 'png', 'bmp', 'tif', 'tiff', 'ico', 'heic', 'webp' ),
|
||||
'audio' => array( 'aac', 'ac3', 'aif', 'aiff', 'flac', 'm3a', 'm4a', 'm4b', 'mka', 'mp1', 'mp2', 'mp3', 'ogg', 'oga', 'ram', 'wav', 'wma' ),
|
||||
'video' => array( '3g2', '3gp', '3gpp', 'asf', 'avi', 'divx', 'dv', 'flv', 'm4v', 'mkv', 'mov', 'mp4', 'mpeg', 'mpg', 'mpv', 'ogm', 'ogv', 'qt', 'rm', 'vob', 'wmv' ),
|
||||
'document' => array( 'doc', 'docx', 'docm', 'dotm', 'odt', 'pages', 'pdf', 'xps', 'oxps', 'rtf', 'wp', 'wpd', 'psd', 'xcf' ),
|
||||
|
||||
@@ -4980,6 +4980,7 @@ function wp_show_heic_upload_error( $plupload_settings ) {
|
||||
* Allows PHP's getimagesize() to be debuggable when necessary.
|
||||
*
|
||||
* @since 5.7.0
|
||||
* @since 5.8.0 Added support for WebP images.
|
||||
*
|
||||
* @param string $filename The file path.
|
||||
* @param array $image_info Optional. Extended image information (passed by reference).
|
||||
@@ -4994,9 +4995,9 @@ function wp_getimagesize( $filename, array &$image_info = null ) {
|
||||
defined( 'WP_DEBUG' ) && WP_DEBUG
|
||||
) {
|
||||
if ( 2 === func_num_args() ) {
|
||||
return getimagesize( $filename, $image_info );
|
||||
return _wp_get_image_size( $filename, $image_info );
|
||||
} else {
|
||||
return getimagesize( $filename );
|
||||
return _wp_get_image_size( $filename );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5011,9 +5012,133 @@ function wp_getimagesize( $filename, array &$image_info = null ) {
|
||||
*/
|
||||
if ( 2 === func_num_args() ) {
|
||||
// phpcs:ignore WordPress.PHP.NoSilencedErrors
|
||||
return @getimagesize( $filename, $image_info );
|
||||
return @_wp_get_image_size( $filename, $image_info );
|
||||
} else {
|
||||
// phpcs:ignore WordPress.PHP.NoSilencedErrors
|
||||
return @getimagesize( $filename );
|
||||
return @_wp_get_image_size( $filename );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts meta information about a webp file: width, height and type.
|
||||
*
|
||||
* @since 5.8.0
|
||||
*
|
||||
* @param [type] $filename Path to a WebP file.
|
||||
* @return array $webp_info {
|
||||
* An array of WebP image information.
|
||||
*
|
||||
* @type array $size {
|
||||
* @type int $width Image width.
|
||||
* @type int $height Image height.
|
||||
* @type bool $type The WebP type: one of 'lossy', 'lossless' or 'animated-alpha'.
|
||||
* }
|
||||
*/
|
||||
function wp_get_webp_info( $filename ) {
|
||||
$width = false;
|
||||
$height = false;
|
||||
$type = false;
|
||||
if ( ! 'image/webp' === wp_get_image_mime( $filename ) ) {
|
||||
return compact( 'width', 'height', 'type' );
|
||||
}
|
||||
try {
|
||||
$handle = fopen( $filename, 'rb' );
|
||||
if ( $handle ) {
|
||||
$magic = fread( $handle, 40 );
|
||||
fclose( $handle );
|
||||
|
||||
// Make sure we got enough bytes.
|
||||
if ( strlen( $magic ) < 40 ) {
|
||||
return compact( 'width', 'height', 'type' );
|
||||
}
|
||||
|
||||
// The headers are a little different for each of the three formats.
|
||||
// Header values based on WebP docs, see https://developers.google.com/speed/webp/docs/riff_container.
|
||||
switch ( substr( $magic, 12, 4 ) ) {
|
||||
// Lossy WebP.
|
||||
case 'VP8 ':
|
||||
$parts = unpack( 'v2', substr( $magic, 26, 4 ) );
|
||||
$width = (int) ( $parts[1] & 0x3FFF );
|
||||
$height = (int) ( $parts[2] & 0x3FFF );
|
||||
$type = 'lossy';
|
||||
break;
|
||||
// Lossless WebP.
|
||||
case 'VP8L':
|
||||
$parts = unpack( 'C4', substr( $magic, 21, 4 ) );
|
||||
$width = (int) ( $parts[1] | ( ( $parts[2] & 0x3F ) << 8 ) ) + 1;
|
||||
$height = (int) ( ( ( $parts[2] & 0xC0 ) >> 6 ) | ( $parts[3] << 2 ) | ( ( $parts[4] & 0x03 ) << 10 ) ) + 1;
|
||||
$type = 'lossless';
|
||||
break;
|
||||
// Animated/alpha WebP.
|
||||
case 'VP8X':
|
||||
// Pad 24-bit int.
|
||||
$width = unpack( 'V', substr( $magic, 24, 3 ) . "\x00" );
|
||||
$width = (int) ( $width[1] & 0xFFFFFF ) + 1;
|
||||
// Pad 24-bit int.
|
||||
$height = unpack( 'V', substr( $magic, 27, 3 ) . "\x00" );
|
||||
$height = (int) ( $height[1] & 0xFFFFFF ) + 1;
|
||||
$type = 'animated-alpha';
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch ( Exception $e ) {
|
||||
}
|
||||
return compact( 'width', 'height', 'type' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if a passed image is a lossy WebP image.
|
||||
*
|
||||
* @since 5.8.0
|
||||
*
|
||||
* @param string $filename The file path.
|
||||
* @return bool Whether the file is a lossy WebP file.
|
||||
*/
|
||||
function _wp_webp_is_lossy( $filename ) {
|
||||
$webp_info = wp_get_webp_info( $filename );
|
||||
$type = $webp_info['type'];
|
||||
return $type && 'lossy' === $type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the image size, with support for WebP images.
|
||||
*
|
||||
* @since 5.8.0
|
||||
* @access private
|
||||
*
|
||||
* @param string $filename The file path.
|
||||
* @param array $imageinfo Extended image information, passed by reference.
|
||||
* @return array|false Array of image information or false on failure.
|
||||
*/
|
||||
function _wp_get_image_size( $filename, &$imageinfo = array() ) {
|
||||
// Try getimagesize() first.
|
||||
$info = getimagesize( $filename, $imageinfo );
|
||||
if ( false !== $info ) {
|
||||
return $info;
|
||||
}
|
||||
// For PHP versions that don't support WebP images, extract the image
|
||||
// size info from the file headers.
|
||||
if ( 'image/webp' === wp_get_image_mime( $filename ) ) {
|
||||
$webp_info = wp_get_webp_info( $filename );
|
||||
$width = $webp_info['width'];
|
||||
$height = $webp_info['height'];
|
||||
|
||||
// Mimic the native return format.
|
||||
if ( $width && $height ) {
|
||||
return array(
|
||||
$width,
|
||||
$height,
|
||||
IMAGETYPE_WEBP, // phpcs:ignore PHPCompatibility.Constants.NewConstants.imagetype_webpFound
|
||||
sprintf(
|
||||
'width="%d" height="%d"',
|
||||
$width,
|
||||
$height
|
||||
),
|
||||
'mime' => 'image/webp',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// The image could not be parsed.
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -6539,7 +6539,7 @@ function wp_attachment_is( $type, $post = null ) {
|
||||
|
||||
switch ( $type ) {
|
||||
case 'image':
|
||||
$image_exts = array( 'jpg', 'jpeg', 'jpe', 'gif', 'png' );
|
||||
$image_exts = array( 'jpg', 'jpeg', 'jpe', 'gif', 'png', 'webp' );
|
||||
return in_array( $ext, $image_exts, true );
|
||||
|
||||
case 'audio':
|
||||
|
||||
@@ -438,7 +438,7 @@ class WP_REST_Attachments_Controller extends WP_REST_Posts_Controller {
|
||||
);
|
||||
}
|
||||
|
||||
$supported_types = array( 'image/jpeg', 'image/png', 'image/gif' );
|
||||
$supported_types = array( 'image/jpeg', 'image/png', 'image/gif', 'image/webp' );
|
||||
$mime_type = get_post_mime_type( $attachment_id );
|
||||
if ( ! in_array( $mime_type, $supported_types, true ) ) {
|
||||
return new WP_Error(
|
||||
|
||||
BIN
tests/phpunit/data/images/test-image.webp
Normal file
BIN
tests/phpunit/data/images/test-image.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 366 B |
BIN
tests/phpunit/data/images/webp-animated.webp
Normal file
BIN
tests/phpunit/data/images/webp-animated.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 508 B |
BIN
tests/phpunit/data/images/webp-lossless.webp
Normal file
BIN
tests/phpunit/data/images/webp-lossless.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 570 KiB |
BIN
tests/phpunit/data/images/webp-lossy.webp
Normal file
BIN
tests/phpunit/data/images/webp-lossy.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 42 KiB |
BIN
tests/phpunit/data/images/webp-transparent.webp
Normal file
BIN
tests/phpunit/data/images/webp-transparent.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 58 KiB |
@@ -1225,6 +1225,29 @@ class Tests_Functions extends WP_UnitTestCase {
|
||||
$this->assertSame( $expected, wp_get_image_mime( $file ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 35725
|
||||
* @dataProvider data_wp_getimagesize
|
||||
*/
|
||||
public function test_wp_getimagesize( $file, $expected ) {
|
||||
if ( ! is_callable( 'exif_imagetype' ) && ! function_exists( 'getimagesize' ) ) {
|
||||
$this->markTestSkipped( 'The exif PHP extension is not loaded.' );
|
||||
}
|
||||
|
||||
$result = wp_getimagesize( $file );
|
||||
|
||||
// The getimagesize() function varies in its response, so
|
||||
// let's restrict comparison to expected keys only.
|
||||
if ( is_array( $expected ) ) {
|
||||
foreach ( $expected as $k => $v ) {
|
||||
$this->assertEquals( true, isset( $result[ $k ] ) );
|
||||
$this->assertEquals( $expected[ $k ], $result[ $k ] );
|
||||
}
|
||||
} else {
|
||||
$this->assertEquals( $expected, $result );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @ticket 39550
|
||||
* @dataProvider _wp_check_filetype_and_ext_data
|
||||
@@ -1313,6 +1336,129 @@ class Tests_Functions extends WP_UnitTestCase {
|
||||
DIR_TESTDATA . '/images/test-image-mime-jpg.png',
|
||||
'image/jpeg',
|
||||
),
|
||||
// Animated WebP.
|
||||
array(
|
||||
DIR_TESTDATA . '/images/webp-animated.webp',
|
||||
'image/webp',
|
||||
),
|
||||
// Lossless WebP.
|
||||
array(
|
||||
DIR_TESTDATA . '/images/webp-lossless.webp',
|
||||
'image/webp',
|
||||
),
|
||||
// Lossy WebP.
|
||||
array(
|
||||
DIR_TESTDATA . '/images/webp-lossy.webp',
|
||||
'image/webp',
|
||||
),
|
||||
// Transparent WebP.
|
||||
array(
|
||||
DIR_TESTDATA . '/images/webp-transparent.webp',
|
||||
'image/webp',
|
||||
),
|
||||
// Not an image.
|
||||
array(
|
||||
DIR_TESTDATA . '/uploads/dashicons.woff',
|
||||
false,
|
||||
),
|
||||
);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Data profider for test_wp_getimagesize();
|
||||
*/
|
||||
public function data_wp_getimagesize() {
|
||||
$data = array(
|
||||
// Standard JPEG.
|
||||
array(
|
||||
DIR_TESTDATA . '/images/test-image.jpg',
|
||||
array(
|
||||
50,
|
||||
50,
|
||||
IMAGETYPE_JPEG,
|
||||
'width="50" height="50"',
|
||||
'mime' => 'image/jpeg',
|
||||
),
|
||||
),
|
||||
// Standard GIF.
|
||||
array(
|
||||
DIR_TESTDATA . '/images/test-image.gif',
|
||||
array(
|
||||
50,
|
||||
50,
|
||||
IMAGETYPE_GIF,
|
||||
'width="50" height="50"',
|
||||
'mime' => 'image/gif',
|
||||
),
|
||||
),
|
||||
// Standard PNG.
|
||||
array(
|
||||
DIR_TESTDATA . '/images/test-image.png',
|
||||
array(
|
||||
50,
|
||||
50,
|
||||
IMAGETYPE_PNG,
|
||||
'width="50" height="50"',
|
||||
'mime' => 'image/png',
|
||||
),
|
||||
),
|
||||
// Image with wrong extension.
|
||||
array(
|
||||
DIR_TESTDATA . '/images/test-image-mime-jpg.png',
|
||||
array(
|
||||
50,
|
||||
50,
|
||||
IMAGETYPE_JPEG,
|
||||
'width="50" height="50"',
|
||||
'mime' => 'image/jpeg',
|
||||
),
|
||||
),
|
||||
// Animated WebP.
|
||||
array(
|
||||
DIR_TESTDATA . '/images/webp-animated.webp',
|
||||
array(
|
||||
100,
|
||||
100,
|
||||
IMAGETYPE_WEBP,
|
||||
'width="100" height="100"',
|
||||
'mime' => 'image/webp',
|
||||
),
|
||||
),
|
||||
// Lossless WebP.
|
||||
array(
|
||||
DIR_TESTDATA . '/images/webp-lossless.webp',
|
||||
array(
|
||||
1200,
|
||||
675,
|
||||
IMAGETYPE_WEBP,
|
||||
'width="1200" height="675"',
|
||||
'mime' => 'image/webp',
|
||||
),
|
||||
),
|
||||
// Lossy WebP.
|
||||
array(
|
||||
DIR_TESTDATA . '/images/webp-lossy.webp',
|
||||
array(
|
||||
1200,
|
||||
675,
|
||||
IMAGETYPE_WEBP,
|
||||
'width="1200" height="675"',
|
||||
'mime' => 'image/webp',
|
||||
),
|
||||
),
|
||||
// Transparent WebP.
|
||||
array(
|
||||
DIR_TESTDATA . '/images/webp-transparent.webp',
|
||||
array(
|
||||
1200,
|
||||
675,
|
||||
IMAGETYPE_WEBP,
|
||||
'width="1200" height="675"',
|
||||
'mime' => 'image/webp',
|
||||
),
|
||||
),
|
||||
// Not an image.
|
||||
array(
|
||||
DIR_TESTDATA . '/uploads/dashicons.woff',
|
||||
|
||||
@@ -195,4 +195,84 @@ class Tests_Image_Editor extends WP_Image_UnitTestCase {
|
||||
|
||||
$this->assertSame( '100x50', $editor->get_suffix() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Test wp_get_webp_info.
|
||||
*
|
||||
* @ticket 35725
|
||||
* @dataProvider _test_wp_get_webp_info
|
||||
*
|
||||
*/
|
||||
public function test_wp_get_webp_info( $file, $expected ) {
|
||||
$editor = wp_get_image_editor( $file );
|
||||
if ( is_wp_error( $editor ) || ! $editor->supports_mime_type( 'image/webp' ) ) {
|
||||
$this->markTestSkipped( sprintf( 'Skipping test: no WebP support in the editor engine %s on this system.', $this->editor_engine ) );
|
||||
} else {
|
||||
$file_data = wp_get_webp_info( $file );
|
||||
$this->assertSame( $file_data, $expected );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for test_wp_get_webp_info();
|
||||
*/
|
||||
public function _test_wp_get_webp_info() {
|
||||
return array(
|
||||
// Standard JPEG.
|
||||
array(
|
||||
DIR_TESTDATA . '/images/test-image.jpg',
|
||||
array(
|
||||
'width' => false,
|
||||
'height' => false,
|
||||
'type' => false,
|
||||
),
|
||||
),
|
||||
// Standard GIF.
|
||||
array(
|
||||
DIR_TESTDATA . '/images/test-image.gif',
|
||||
array(
|
||||
'width' => false,
|
||||
'height' => false,
|
||||
'type' => false,
|
||||
),
|
||||
),
|
||||
// Animated WebP.
|
||||
array(
|
||||
DIR_TESTDATA . '/images/webp-animated.webp',
|
||||
array(
|
||||
'width' => 100,
|
||||
'height' => 100,
|
||||
'type' => 'animated-alpha',
|
||||
),
|
||||
),
|
||||
// Lossless WebP.
|
||||
array(
|
||||
DIR_TESTDATA . '/images/webp-lossless.webp',
|
||||
array(
|
||||
'width' => 1200,
|
||||
'height' => 675,
|
||||
'type' => 'lossless',
|
||||
),
|
||||
),
|
||||
// Lossy WebP.
|
||||
array(
|
||||
DIR_TESTDATA . '/images/webp-lossy.webp',
|
||||
array(
|
||||
'width' => 1200,
|
||||
'height' => 675,
|
||||
'type' => 'lossy',
|
||||
),
|
||||
),
|
||||
// Transparent WebP.
|
||||
array(
|
||||
DIR_TESTDATA . '/images/webp-transparent.webp',
|
||||
array(
|
||||
'width' => 1200,
|
||||
'height' => 675,
|
||||
'type' => 'animated-alpha',
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -59,6 +59,10 @@ class Tests_Image_Functions extends WP_UnitTestCase {
|
||||
'test-image.psd',
|
||||
'test-image-zip.tiff',
|
||||
'test-image.jpg',
|
||||
'webp-animated.webp',
|
||||
'webp-lossless.webp',
|
||||
'webp-lossy.webp',
|
||||
'webp-transparent.webp',
|
||||
);
|
||||
|
||||
// IMAGETYPE_ICO is only defined in PHP 5.3+.
|
||||
@@ -92,6 +96,21 @@ class Tests_Image_Functions extends WP_UnitTestCase {
|
||||
'test-image.jpg',
|
||||
);
|
||||
|
||||
// Add WebP images if the image editor supports them.
|
||||
$file = DIR_TESTDATA . '/images/test-image.webp';
|
||||
$editor = wp_get_image_editor( $file );
|
||||
if ( ( ! is_wp_error( $editor ) ) && $editor->supports_mime_type( 'image/webp' ) ) {
|
||||
$files = array_merge(
|
||||
$files,
|
||||
array(
|
||||
'webp-animated.webp',
|
||||
'webp-lossless.webp',
|
||||
'webp-lossy.webp',
|
||||
'webp-transparent.webp',
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// IMAGETYPE_ICO is only defined in PHP 5.3+.
|
||||
if ( defined( 'IMAGETYPE_ICO' ) ) {
|
||||
$files[] = 'test-image.ico';
|
||||
@@ -174,6 +193,11 @@ class Tests_Image_Functions extends WP_UnitTestCase {
|
||||
'image/png',
|
||||
);
|
||||
|
||||
// Include WebP in tests when platform supports it.
|
||||
if ( function_exists( 'imagewebp' ) ) {
|
||||
array_push( $mime_types, 'image/webp' );
|
||||
}
|
||||
|
||||
// Test each image editor engine.
|
||||
foreach ( $classes as $class ) {
|
||||
$img = new $class( DIR_TESTDATA . '/images/canola.jpg' );
|
||||
@@ -270,7 +294,8 @@ class Tests_Image_Functions extends WP_UnitTestCase {
|
||||
'jpe' => 'image/jpeg',
|
||||
'gif' => 'image/gif',
|
||||
'png' => 'image/png',
|
||||
'unk' => 'image/jpeg', // Default, unknown.
|
||||
'webp' => 'image/webp',
|
||||
'unk' => 'image/jpeg', // Default, unknown.
|
||||
);
|
||||
|
||||
// Test each image editor engine.
|
||||
|
||||
@@ -64,6 +64,24 @@ abstract class WP_Tests_Image_Resize_UnitTestCase extends WP_Image_UnitTestCase
|
||||
unlink( $image );
|
||||
}
|
||||
|
||||
function test_resize_webp() {
|
||||
$file = DIR_TESTDATA . '/images/test-image.webp';
|
||||
$editor = wp_get_image_editor( $file );
|
||||
|
||||
// Check if the editor supports the webp mime type.
|
||||
if ( is_wp_error( $editor ) || ! $editor->supports_mime_type( 'image/webp' ) ) {
|
||||
$this->markTestSkipped( sprintf( 'Skipping test: no WebP support in the editor engine %s on this system.', $this->editor_engine ) );
|
||||
} else {
|
||||
$image = $this->resize_helper( $file, 25, 25 );
|
||||
$this->assertSame( 'test-image-25x25.webp', wp_basename( $image ) );
|
||||
list($w, $h, $type) = wp_getimagesize( $image );
|
||||
$this->assertSame( 25, $w );
|
||||
$this->assertSame( 25, $h );
|
||||
$this->assertSame( IMAGETYPE_WEBP, $type );
|
||||
unlink( $image );
|
||||
}
|
||||
}
|
||||
|
||||
function test_resize_larger() {
|
||||
// image_resize() should refuse to make an image larger.
|
||||
$image = $this->resize_helper( DIR_TESTDATA . '/images/test-image.jpg', 100, 100 );
|
||||
|
||||
Reference in New Issue
Block a user