Skip to main content
Update for WPSE2_Image_Editor_GD
Source Link
birgire
  • 67.8k
  • 7
  • 119
  • 251

A workaround by extending the WP_Image_Editor_GD class

  1. A workaround by extending the WP_Image_Editor_GD class

/**
 * Extend the WP_Image_Editor_GD to add the custom wpse_make_image_arguments filter.
 * @see http://wordpress.stackexchange.com/a/165241/26350
 */
add_filter( 'wp_image_editors', function( $editors ) 
{
    // Note that the WP_Image_Editor_GD and WP_Image_Editor_Imagick classes
    // are included within this filter. So let's do the same for our extended class.

    // Our extended class that overrides the WP_Image_Editor_GD::make_image() method

    if( ! class_exists( 'WPSE_Image_Editor_GD' ) )
    {   
        class WPSE_Image_Editor_GD extends WP_Image_Editor_GD
        {
            protected function make_image( $filename, $function, $arguments ) 
            {
                // Add a custom filter      
                $arguments = apply_filters( 'wpse_make_image_arguments', $arguments, $filename, $this->size, $function );

                // Parent method
                return parent::make_image( $filename, $function, $arguments );
            }
        }
    }

    // Prepend the extended class to the array of image editors:    
    array_unshift( $editors, 'WPSE_Image_Editor_GD' );

    return $editors;
} );

PS: I didn't check out the case when the Imagick library is used instead, but I guess we could do something similar by extending the WP_Image_Editor_Imagick class.

  1. Update - Set jpeg quality per image size name

Here's another version where we set the jpeg quality per image size name:

/**
 * Extend the WP_Image_Editor_GD to set quality per image size name.
 * 
 * @see http://wordpress.stackexchange.com/a/165241/26350
 */
add_filter( 'wp_image_editors', function( $editors ) 
{
    // Note that the WP_Image_Editor_GD and WP_Image_Editor_Imagick classes
    // are included within this filter. So let's do the same for our extended class.

    // Our extended class that overrides the WP_Image_Editor_GD::_resize() method
    if( ! class_exists( 'WPSE2_Image_Editor_GD' ) )
    {   
        class WPSE2_Image_Editor_GD extends WP_Image_Editor_GD
        {
            protected function _resize( $max_w, $max_h, $crop = false )
            {
                $qualities = apply_filters( 'wpse_jpeg_qualities', [] );
                $default_quality = (int) apply_filters( 'wpse_default_jpeg_quality', 82 );                              
                $sizes = wp_get_additional_image_sizes();
                $this->set_quality( $default_quality );         
                foreach( (array) $qualities as $name => $quality )
                {
                    if( 
                        isset( $sizes[$name] ) 
                        && (int)  $sizes[$name]['width']  === (int)  $max_w
                        && (int)  $sizes[$name]['height'] === (int)  $max_h
                        && (bool) $sizes[$name]['crop']   === (bool) $crop  
                    )   
                        $this->set_quality( $quality );                 
                }
            
                // Parent method
                return parent::_resize( $max_w, $max_h, $crop );
            }
        }
    }
    
    // Prepend the extended class to the array of image editors:    
    array_unshift( $editors, 'WPSE2_Image_Editor_GD' );
    
    return $editors;
} );

I noticed that the crop arguments can be 0, false or empty, so we do some typecasting to be sure.

Here we've introduced the following new filters:

add_filter( 'wpse_jpeg_qualities', function( $qualities )
{ 
    return [ 'hello-image' => 2, 'medium' => 2, 'large' => 2 ];
} );

and

add_filter( 'wpse_default_jpeg_quality', function( $quality )
{ 
    return 82;
} );

that can hopefully be adjusted to your needs!

A workaround by extending the WP_Image_Editor_GD class

/**
 * Extend the WP_Image_Editor_GD to add the custom wpse_make_image_arguments filter.
 * @see http://wordpress.stackexchange.com/a/165241/26350
 */
add_filter( 'wp_image_editors', function( $editors ) 
{
    // Note that the WP_Image_Editor_GD and WP_Image_Editor_Imagick classes
    // are included within this filter. So let's do the same for our extended class.

    // Our extended class that overrides the WP_Image_Editor_GD::make_image() method
    class WPSE_Image_Editor_GD extends WP_Image_Editor_GD
    {
        protected function make_image( $filename, $function, $arguments ) 
        {
            // Add a custom filter      
            $arguments = apply_filters( 'wpse_make_image_arguments', $arguments, $filename, $this->size, $function );

            // Parent method
            return parent::make_image( $filename, $function, $arguments );
        }
    }

    // Prepend the extended class to the array of image editors:    
    array_unshift( $editors, 'WPSE_Image_Editor_GD' );

    return $editors;
} );

PS: I didn't check out the case when the Imagick library is used instead, but I guess we could do something similar by extending the WP_Image_Editor_Imagick class.

  1. A workaround by extending the WP_Image_Editor_GD class

/**
 * Extend the WP_Image_Editor_GD to add the custom wpse_make_image_arguments filter.
 * @see http://wordpress.stackexchange.com/a/165241/26350
 */
add_filter( 'wp_image_editors', function( $editors ) 
{
    // Note that the WP_Image_Editor_GD and WP_Image_Editor_Imagick classes
    // are included within this filter. So let's do the same for our extended class.

    // Our extended class that overrides the WP_Image_Editor_GD::make_image() method

    if( ! class_exists( 'WPSE_Image_Editor_GD' ) )
    {   
        class WPSE_Image_Editor_GD extends WP_Image_Editor_GD
        {
            protected function make_image( $filename, $function, $arguments ) 
            {
                // Add a custom filter      
                $arguments = apply_filters( 'wpse_make_image_arguments', $arguments, $filename, $this->size, $function );

                // Parent method
                return parent::make_image( $filename, $function, $arguments );
            }
        }
    }

    // Prepend the extended class to the array of image editors:    
    array_unshift( $editors, 'WPSE_Image_Editor_GD' );

    return $editors;
} );

PS: I didn't check out the case when the Imagick library is used instead, but I guess we could do something similar by extending the WP_Image_Editor_Imagick class.

  1. Update - Set jpeg quality per image size name

Here's another version where we set the jpeg quality per image size name:

/**
 * Extend the WP_Image_Editor_GD to set quality per image size name.
 * 
 * @see http://wordpress.stackexchange.com/a/165241/26350
 */
add_filter( 'wp_image_editors', function( $editors ) 
{
    // Note that the WP_Image_Editor_GD and WP_Image_Editor_Imagick classes
    // are included within this filter. So let's do the same for our extended class.

    // Our extended class that overrides the WP_Image_Editor_GD::_resize() method
    if( ! class_exists( 'WPSE2_Image_Editor_GD' ) )
    {   
        class WPSE2_Image_Editor_GD extends WP_Image_Editor_GD
        {
            protected function _resize( $max_w, $max_h, $crop = false )
            {
                $qualities = apply_filters( 'wpse_jpeg_qualities', [] );
                $default_quality = (int) apply_filters( 'wpse_default_jpeg_quality', 82 );                              
                $sizes = wp_get_additional_image_sizes();
                $this->set_quality( $default_quality );         
                foreach( (array) $qualities as $name => $quality )
                {
                    if( 
                        isset( $sizes[$name] ) 
                        && (int)  $sizes[$name]['width']  === (int)  $max_w
                        && (int)  $sizes[$name]['height'] === (int)  $max_h
                        && (bool) $sizes[$name]['crop']   === (bool) $crop  
                    )   
                        $this->set_quality( $quality );                 
                }
            
                // Parent method
                return parent::_resize( $max_w, $max_h, $crop );
            }
        }
    }
    
    // Prepend the extended class to the array of image editors:    
    array_unshift( $editors, 'WPSE2_Image_Editor_GD' );
    
    return $editors;
} );

I noticed that the crop arguments can be 0, false or empty, so we do some typecasting to be sure.

Here we've introduced the following new filters:

add_filter( 'wpse_jpeg_qualities', function( $qualities )
{ 
    return [ 'hello-image' => 2, 'medium' => 2, 'large' => 2 ];
} );

and

add_filter( 'wpse_default_jpeg_quality', function( $quality )
{ 
    return 82;
} );

that can hopefully be adjusted to your needs!

Some light adjustments
Source Link
birgire
  • 67.8k
  • 7
  • 119
  • 251
/**
 * Set image (jpgjpeg) quality based on the image size (width/height)
 * @see http://wordpress.stackexchange.com/a/165241/26350
 */
add_filter( 'wpse_make_image_arguments', function( $arguments, $filename, $size, $function ) 
{   
    // Only target jpeg cases, i.e. with the quality set in $arguments[2]       
    if( ! isset( $size['height'] ) || ! isset( $size['width'] ) || ! isset( $arguments[2] ) )
        return $arguments;
        
    // Modify this part to your needs:
    if( $size['height'] <= 150  && $size['width'] <= 150 )
        $arguments[2] = 2; // very low quality for easy testing
   
    return $arguments;
}, 10, 4 );
/**
 * Extend the WP_Image_Editor_GD to add the custom wpse_make_image_arguments filter.
 * @see http://wordpress.stackexchange.com/a/165241/26350
 */
add_filter( 'wp_image_editors', function( $editors )  
{
    // Note that the WP_Image_Editor_GD and WP_Image_Editor_Imagick classes
    // are included within this filter. So let's do the same for our extensionextended class.

    // Our extended class that overrides the WP_Image_Editor_GD::make_image() method
    class WPSE_Image_Editor_GD extends WP_Image_Editor_GD
    {
        protected function make_image( $filename, $function, $arguments ) {
        {
    // Add a custom filter:    // Add a custom filter      
            $arguments = apply_filters( 'wpse_make_image_arguments', $arguments, $filename, $this->size, $function );

            // Parent method
            return parent::make_image( $filename, $function, $arguments );
        }
    }

    // Prepend the extended class to the array of image editors:    
    array_unshift( $editors, 'WPSE_Image_Editor_GD' );

    return $editors;
} );
/**
 * Set image (jpg) quality based on the image size (width/height)
 * @see http://wordpress.stackexchange.com/a/165241/26350
 */
add_filter( 'wpse_make_image_arguments', function( $arguments, $filename, $size, $function ) 
{   
    // Only target jpeg cases, i.e. with the quality set in $arguments[2]       
    if( ! isset( $size['height'] ) || ! isset( $size['width'] ) || ! isset( $arguments[2] ) )
        return $arguments;
        
    // Modify this part to your needs:
    if( $size['height'] <= 150  && $size['width'] <= 150 )
        $arguments[2] = 2; // very low quality for easy testing
   
    return $arguments;
}, 10, 4 );
/**
 * Extend the WP_Image_Editor_GD to add the custom wpse_make_image_arguments filter.
 * @see http://wordpress.stackexchange.com/a/165241/26350
 */
add_filter( 'wp_image_editors', function( $editors ) {
    // Note that the WP_Image_Editor_GD and WP_Image_Editor_Imagick classes
    // are included within this filter. So let's do the same for our extension class.

    // Our extended class:
    class WPSE_Image_Editor_GD extends WP_Image_Editor_GD
    {
        protected function make_image( $filename, $function, $arguments ) {
            // Add a custom filter:             
            $arguments = apply_filters( 'wpse_make_image_arguments', $arguments, $filename, $this->size, $function );

            // Parent method
            return parent::make_image( $filename, $function, $arguments );
        }
    }

    // Prepend the extended class to the array of image editors:    
    array_unshift( $editors, 'WPSE_Image_Editor_GD' );

    return $editors;
} );
/**
 * Set image (jpeg) quality based on the image size (width/height)
 * @see http://wordpress.stackexchange.com/a/165241/26350
 */
add_filter( 'wpse_make_image_arguments', function( $arguments, $filename, $size, $function ) 
{   
    // Only target jpeg cases, i.e. with the quality set in $arguments[2]       
    if( ! isset( $size['height'] ) || ! isset( $size['width'] ) || ! isset( $arguments[2] ) )
        return $arguments;
        
    // Modify this part to your needs:
    if( $size['height'] <= 150  && $size['width'] <= 150 )
        $arguments[2] = 2; // very low quality for easy testing
   
    return $arguments;
}, 10, 4 );
/**
 * Extend the WP_Image_Editor_GD to add the custom wpse_make_image_arguments filter.
 * @see http://wordpress.stackexchange.com/a/165241/26350
 */
add_filter( 'wp_image_editors', function( $editors )  
{
    // Note that the WP_Image_Editor_GD and WP_Image_Editor_Imagick classes
    // are included within this filter. So let's do the same for our extended class.

    // Our extended class that overrides the WP_Image_Editor_GD::make_image() method
    class WPSE_Image_Editor_GD extends WP_Image_Editor_GD
    {
        protected function make_image( $filename, $function, $arguments ) 
        {
            // Add a custom filter      
            $arguments = apply_filters( 'wpse_make_image_arguments', $arguments, $filename, $this->size, $function );

            // Parent method
            return parent::make_image( $filename, $function, $arguments );
        }
    }

    // Prepend the extended class to the array of image editors:    
    array_unshift( $editors, 'WPSE_Image_Editor_GD' );

    return $editors;
} );
Some light adjustments
Source Link
birgire
  • 67.8k
  • 7
  • 119
  • 251
/**
 * Set image (jpg) quality based on the image size (width/height)
 * @see http://wordpress.stackexchange.com/a/165241/26350
 */
add_filter( 'jpeg_quality', function( $quality ) {
    add_filter( 'wpse_make_image_arguments', 
        function( $arguments, $filename, $function$size, $size$function )  
{       
 
            // --------------------------------------------
            // Extract the width/height from the $size 
         Only target jpeg //cases, andi.e. modifywith the quality settingsset in $arguments[2] accordingly:
         
    if( ! isset( $size['height'] ) &&|| ! isset( $size['width'] ) &&|| ! isset( $arguments[2] ) ){ 
  
       return $arguments;
        
    // Modify this part to your needs:
                if( $size['height'] <= 150  && $size['width'] <= 150 ) {
                    $arguments[2] = 50; 
                }
            }
           2; // --------------------------------------------

very low quality for easy testing
    
    return $arguments;
        }, 10, 4 );
    return $quality;
} );
/**
 * Extend the WP_Image_Editor_GD to add the custom wpse_make_image_arguments filter.
 * @see http://wordpress.stackexchange.com/a/165241/26350
 */
add_filter( 'wp_image_editors', function( $editors ) {
    // Note that the WP_Image_Editor_GD and WP_Image_Editor_Imagick classes
    // are included within this filter. So let's do the same for our extension class.

    // Our extended class:
    class WP_Image_Editor_GD_WPSEWPSE_Image_Editor_GD extends WP_Image_Editor_GD
    {
        protected function make_image( $filename, $function, $arguments ) {
            if ( wp_is_stream( $filename ) )
                $arguments[1] = null;

            // Add a custom filter:             
            $arguments = apply_filters( 'wpse_make_image_arguments', 
  $arguments, $filename, $this->size, $function );

          $arguments, $filename, $this->size,// $functionParent );method
            return parent::make_image( $filename, $function, $arguments );
        }
    } 

    // Prepend the extended class to the array of image editors:    
    array_unshift( $editors, 'WP_Image_Editor_GD_WPSE''WPSE_Image_Editor_GD' ); 

    return $editors;
} );
/**
 * Set image (jpg) quality based on the image size (width/height)
 * @see http://wordpress.stackexchange.com/a/165241/26350
 */
add_filter( 'jpeg_quality', function( $quality ) {
    add_filter( 'wpse_make_image_arguments', 
        function( $arguments, $filename, $function, $size ) {       
 
            // --------------------------------------------
            // Extract the width/height from the $size 
            // and modify the quality settings in $arguments[2] accordingly:
            if( isset($size['height']) && isset($size['width']) && isset($arguments[2]) ){  
                 // Modify this part to your needs:
                if( $size['height'] <= 150  && $size['width'] <= 150 ) {
                    $arguments[2] = 50; 
                }
            }
            // --------------------------------------------

            return $arguments;
        }, 10, 4 );
    return $quality;
} );
/**
 * Extend the WP_Image_Editor_GD to add the custom wpse_make_image_arguments filter.
 * @see http://wordpress.stackexchange.com/a/165241/26350
 */
add_filter( 'wp_image_editors', function( $editors ) {
    // Note that the WP_Image_Editor_GD and WP_Image_Editor_Imagick classes
    // are included within this filter. So let's do the same for our extension class.

    // Our extended class:
    class WP_Image_Editor_GD_WPSE extends WP_Image_Editor_GD
    {
        protected function make_image( $filename, $function, $arguments ) {
            if ( wp_is_stream( $filename ) )
                $arguments[1] = null;

            // Add a custom filter:             
            $arguments = apply_filters( 'wpse_make_image_arguments', 
                $arguments, $filename, $this->size, $function );
            return parent::make_image( $filename, $function, $arguments );
        }
    }
    // Prepend the extended class to the array of image editors:    
    array_unshift( $editors, 'WP_Image_Editor_GD_WPSE' );
    return $editors;
} );
/**
 * Set image (jpg) quality based on the image size (width/height)
 * @see http://wordpress.stackexchange.com/a/165241/26350
 */
add_filter( 'wpse_make_image_arguments', function( $arguments, $filename, $size, $function )  
{   
    // Only target jpeg cases, i.e. with the quality set in $arguments[2]        
    if( ! isset( $size['height'] ) || ! isset( $size['width'] ) || ! isset( $arguments[2] ) ) 
        return $arguments;
        
    // Modify this part to your needs:
    if( $size['height'] <= 150  && $size['width'] <= 150 )
        $arguments[2] = 2; // very low quality for easy testing
    
    return $arguments;
}, 10, 4 );
/**
 * Extend the WP_Image_Editor_GD to add the custom wpse_make_image_arguments filter.
 * @see http://wordpress.stackexchange.com/a/165241/26350
 */
add_filter( 'wp_image_editors', function( $editors ) {
    // Note that the WP_Image_Editor_GD and WP_Image_Editor_Imagick classes
    // are included within this filter. So let's do the same for our extension class.

    // Our extended class:
    class WPSE_Image_Editor_GD extends WP_Image_Editor_GD
    {
        protected function make_image( $filename, $function, $arguments ) {
            // Add a custom filter:             
            $arguments = apply_filters( 'wpse_make_image_arguments', $arguments, $filename, $this->size, $function );

            // Parent method
            return parent::make_image( $filename, $function, $arguments );
        }
    } 

    // Prepend the extended class to the array of image editors:    
    array_unshift( $editors, 'WPSE_Image_Editor_GD' ); 

    return $editors;
} );
Bounty Ended with 150 reputation awarded by CommunityBot
deleted 1 character in body
Source Link
birgire
  • 67.8k
  • 7
  • 119
  • 251
Loading
added 229 characters in body
Source Link
birgire
  • 67.8k
  • 7
  • 119
  • 251
Loading
Source Link
birgire
  • 67.8k
  • 7
  • 119
  • 251
Loading