Make WordPress Core


Ignore:
Timestamp:
02/02/2024 05:46:50 PM (3 years ago)
Author:
adamsilverstein
Message:

Media: enable AVIF support.

Add support for uploading, editing and saving AVIF images when supported by the server.

Add 'image/avif' to supported mime types. Correctly identify AVIF images and sizes even when PHP doesn't support AVIF. Resize uploaded AVIF files (when supported) and use for front end markup.

Props adamsilverstein, lukefiretoss, ayeshrajans, navjotjsingh, Tyrannous, jb510, gregbenz, nickpagz, JavierCasares, mukesh27, yguyon, swissspidy.
Fixes #51228.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/media.php

    r57294 r57524  
    41014101        require_once ABSPATH . WPINC . '/class-wp-image-editor-gd.php';
    41024102        require_once ABSPATH . WPINC . '/class-wp-image-editor-imagick.php';
     4103        require_once ABSPATH . WPINC . '/class-avif-info.php';
    41034104        /**
    41044105         * Filters the list of image editing library classes.
     
    42034204        if ( ! wp_image_editor_supports( array( 'mime_type' => 'image/webp' ) ) ) {
    42044205                $defaults['webp_upload_error'] = true;
     4206        }
     4207
     4208        // Check if AVIF images can be edited.
     4209        if ( ! wp_image_editor_supports( array( 'mime_type' => 'image/avif' ) ) ) {
     4210                $defaults['avif_upload_error'] = true;
    42054211        }
    42064212
     
    54815487 * @since 5.7.0
    54825488 * @since 5.8.0 Added support for WebP images.
     5489 * @since 6.5.0 Added support for AVIF images.
    54835490 *
    54845491 * @param string $filename   The file path.
     
    55135520        }
    55145521
    5515         if ( false !== $info ) {
     5522        if (
     5523                ! empty( $info ) &&
     5524                // Some PHP versions return 0x0 sizes from `getimagesize` for unrecognized image formats, including AVIFs.
     5525                ! ( empty( $info[0] ) && empty( $info[1] ) )
     5526        ) {
    55165527                return $info;
    55175528        }
     
    55425553        }
    55435554
     5555        // For PHP versions that don't support AVIF images, extract the image size info from the file headers.
     5556        if ( 'image/avif' === wp_get_image_mime( $filename ) ) {
     5557                $avif_info = wp_get_avif_info( $filename );
     5558
     5559                $width  = $avif_info['width'];
     5560                $height = $avif_info['height'];
     5561
     5562                // Mimic the native return format.
     5563                if ( $width && $height ) {
     5564                        return array(
     5565                                $width,
     5566                                $height,
     5567                                IMAGETYPE_AVIF,
     5568                                sprintf(
     5569                                        'width="%d" height="%d"',
     5570                                        $width,
     5571                                        $height
     5572                                ),
     5573                                'mime' => 'image/avif',
     5574                        );
     5575                }
     5576        }
     5577
    55445578        // The image could not be parsed.
    55455579        return false;
     5580}
     5581
     5582/**
     5583 * Extracts meta information about an AVIF file: width, height, bit depth, and number of channels.
     5584 *
     5585 * @since 6.5.0
     5586 *
     5587 * @param string $filename Path to an AVIF file.
     5588 * @return array {
     5589 *    An array of AVIF image information.
     5590 *
     5591 *    @type int|false $width        Image width on success, false on failure.
     5592 *    @type int|false $height       Image height on success, false on failure.
     5593 *    @type int|false $bit_depth    Image bit depth on success, false on failure.
     5594 *    @type int|false $num_channels Image number of channels on success, false on failure.
     5595 * }
     5596 */
     5597function wp_get_avif_info( $filename ) {
     5598        $results = array(
     5599                'width'        => false,
     5600                'height'       => false,
     5601                'bit_depth'    => false,
     5602                'num_channels' => false,
     5603        );
     5604
     5605        if ( 'image/avif' !== wp_get_image_mime( $filename ) ) {
     5606                return $results;
     5607        }
     5608
     5609        // Parse the file using libavifinfo's PHP implementation.
     5610        require_once ABSPATH . WPINC . '/class-avif-info.php';
     5611
     5612        $handle = fopen( $filename, 'rb' );
     5613        if ( $handle ) {
     5614                $parser  = new Avifinfo\Parser( $handle );
     5615                $success = $parser->parse_ftyp() && $parser->parse_file();
     5616                fclose( $handle );
     5617                if ( $success ) {
     5618                        $results = $parser->features->primary_item_features;
     5619                }
     5620        }
     5621        return $results;
    55465622}
    55475623
Note: See TracChangeset for help on using the changeset viewer.