我试图提出一个解决方案,在 WP 管理中上传新项目时,生成的图像格式涵盖响应式和高分辨率方面。我整理了一组应该满足这些要求的格式,

2560 x 1600 视网膜桌面(“largex2”,自定义)
1280 x 800 桌面(大)
1920 x 1200 视网膜平板电脑(“mediumx2”,自定义)
960 x 600 平板电脑 + 视网膜手机(中)
480 x 300 移动设备(缩略图)

我的问题在于较大尺寸的图像质量。以高或非常高的质量设置从 Photoshop 导出图像对于默认尺寸会产生不错的结果,但是自定义尺寸呢?我宁愿以中或低设置导出,以保持合理的文件大小。

我的想法是 - 是否有可能以高质量拍摄一张非常大的图像,上传它,然后进行设置,以便以低得多的质量生成更大的尺寸?

任何帮助表示赞赏!请不要引导我使用任何插件,我想为此构建自己的解决方案。

有帮助吗?

解决方案

1)通过扩展的解决方法 WP_Image_Editor_GD 班级

问题是如何在改变中间质量之前访问图像尺寸 JPEG 图片。

请注意, image_resize() 函数是 已弃用.

我们可以使用 jpeg_quality 过滤掉公众 get_quality 摘要方法 WP_Image_Editor 班级:

$quality = apply_filters( 'jpeg_quality', $quality, 'image_resize' );

或者 wp_editor_set_quality 筛选。

以下是如何根据图像尺寸(宽度/高度)设置图像质量的一种想法:

/**
 * 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 );

我们已经扩展了 WP_Image_Editor_GD 班级:

/**
 * 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;
} );

我们在这里介绍了习俗 wpse_make_image_arguments 筛选。

这样我们就可以修改质量设置, 中间文件被保存。

这是一个例子:

Example

附: 我当时没查这个案子 意马吉克 而是使用库,但我想我们可以通过扩展来做类似的事情 WP_Image_Editor_Imagick 班级。

2) 更新 - 根据图像大小名称设置 jpeg 质量

这是另一个版本,我们根据图像大小名称设置 jpeg 质量:

/**
 * 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;
} );

我注意到裁剪参数可以是 0、false 或空,所以我们做了一些类型转换来确定。

在这里,我们引入了以下新过滤器:

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

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

希望可以根据您的需求进行调整!

其他提示

无法发表评论,必须与另一个版本一起发布。

问题:

我不确定是否 更新 2) 根据图像大小名称设置 jpeg 质量 已接受的答案已完成。 wp_get_additional_image_sizes() 返回 global $_wp_additional_image_sizes 并且不包含有关默认大小(如中号、大号或缩略图)的任何信息。

这在过滤器中可能不起作用:'大' => 2

作为 https://codex.wordpress.org/Function_Reference/get_intermediate_image_sizes 使用自定义代码解释如何使用自定义函数检索所有尺寸。

我对吗?

其次,按名称过滤不同“大小”的想法很棘手。 _resize( $max_w, $max_h, $crop = false ) 只理解并解析匹配的宽度、高度和裁剪值以及每个匹配 认为 来匹配一个名字。但在许多情况下,该名称将是“另一个”名称。

具有相同“shop_product”设置的“中”图像设置将仅“访问”此函数作为其中之一。然后我们不知道被过滤的是“中”尺寸还是“shop_product”尺寸。因为,这里的目标只是图像的技术裁剪。

这个想法与 更新2) 是一个更逻辑的处理,但恐怕技术架构不存在。在构建过滤器之前分析所有注册的图像尺寸,变得更加复杂,以确保意图返回当前主题的正确质量图像程序。

所有具有相等设置的尺寸名称将共享与服务器上共享相同图像相同的新质量。

所以,如果你还坚持 更新2) 我认为你需要调用另一个函数来填充 $sizes 变量,并通过 var_dump() 进行分析 $_wp_additional_image_sizes 对于相同的设置。

该方法在 1)解决方法... 更具逻辑/语义。我们通过相同的扩展方法解决了这个问题,但使用了动态过滤器:

add_filter('wp_image_editors', function($editors){

    if(!class_exists('ENTEX_Image_Editor_GD')){   
        class ENTEX_Image_Editor_GD extends WP_Image_Editor_GD {
            private $wp_quality = null;
            protected function _resize($max_w, $max_h, $crop = false){
                $condition = ($crop ? 'true' : 'false');
                if($this->wp_quality === null) $this->wp_quality = $this->get_quality();
                $quality = apply_filters('wp_editor_set_quality_'. $max_w .'x'. $max_h .'_'. $condition, $this->wp_quality);                              
                $this->set_quality((int) $quality);
                return parent::_resize( $max_w, $max_h, $crop );
            }
        }
    }    
    array_unshift($editors, 'ENTEX_Image_Editor_GD');
    return $editors;
});

为了过滤每个单独的图像大小,我们使用:

add_filter('wp_editor_set_quality_160x160_true', function($quality){
    return 96;
});

与此扩展版本的不同之处在于我们正在使用/填充 add_filter('jpeg_quality' ... 版本作为默认值。

以下是自定义过滤器的一些其他示例:

function high_quality_on_medium_images(){
    $in = 'medium';
    $max_w = get_option($in.'_size_w');
    $max_h = get_option($in.'_size_h');
    $crop = get_option($in.'_crop');
    $condition = ($crop ? 'true' : 'false');
    add_filter('wp_editor_set_quality_'. $max_w .'x'. $max_h .'_'. $condition, 'my_theme_high_quality_images', 10, 1);
}
add_action('after_setup_theme', 'high_quality_on_medium_images', 99);

function my_theme_high_quality_images($quality){
    return (int) 82;
}

开发商关注

  • 在主题图像设置后应用 Shure 滤镜。
  • 不要包裹在里面 is_admin() 然后ajax调用,前端,远程
    发布的图像不会咬人。

如前所述,裁剪值可以是 0 或 false,您必须将 (int) 或 (bool) 转换为字符串 $condition = ($crop ? 'true' : 'false');

主题开发者关注

WP 默认压缩是相当渐进的。值介于 8099 可能会带来巨大的差异 或者 根本没有可见的结果。无压缩值为 100, ,可能返回一个 更大的文件大小 关于“较小尺寸” 800 像素 图片, 然后 原来的大 3000 像素 尺寸版本。

多年后,我们发现了一个神奇的数字 96,文件大小变得更小,但你看不出文件之间的差异 100 价值压缩。

高品质 Photoshop 准备的商店图像,大于 800 像素即可,Wordpress 默认为 82。但 iPhone“大”电子邮件发布的图像在缩略图等小尺寸上确实需要 96 值。它们在 Wordpres 压缩上变得“软化模糊”。

如果您不计划项目,用户或主题的方案,则将过度使用此主题解决方案。

最后的反思

我对 WordPress 感到非常失望,因为在开发的优先级中忽略了这个重要问题,因为图像对于独特有效的加载比以往任何时候都更加重要。

为什么我们不能在正确的位置安装一个可用于单独压缩的过滤器呢?他们费心将“名称”更改为 wp_editor_set_quality,并且 add_filter('jpeg_quality' ... 现已弃用。为什么不认为这是一路走来,只是删除 if ( ! $this->quality ) 仅检查 @birgire 提到的一次方法。

许可以下: CC-BY-SA归因
scroll top