上传时创建不同质量的图像格式

时间:2014-10-08 作者:Staffan Estberg

我正试图想出一个解决方案,在WP admin中上载新项目时,生成的图像格式将覆盖响应和高分辨率两个方面。我已经制定了一套符合这些要求的格式,

2560 x 1600视网膜台式机(\'largex2\',定制)
1280 x 800桌面(大)
1920 x 1200视网膜平板电脑(\'mediumx2\',定制)
960 x 600平板电脑+视网膜移动设备(中)
480 x 300移动设备(缩略图)

我的问题在于较大尺寸的图像质量。从Photoshop中以高或极高的质量设置导出图像将为默认大小产生公平的结果,但自定义大小如何?我宁愿以中等或较低的设置导出这些文件,以保持合理的文件大小

我的想法是-是否有可能以高质量拍摄一幅真正大的图像,上传它,然后进行设置,以便以更低的质量生成更大的图像?

感谢您的帮助!请不要直接告诉我任何插件,我想为此构建自己的解决方案。

2 个回复
最合适的回答,由SO网友:birgire 整理而成

1) 通过扩展WP_Image_Editor_GD 问题是如何在更改中间jpeg图像的质量之前访问图像大小。

请注意image_resize() 函数为deprecated.

我们可以使用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 滤器

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

下面是一个示例:

Example

PS:我没有检查使用Imagick库时的情况,但我想我们可以通过扩展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;
} );
我注意到crop参数可以是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;
} );
希望可以根据您的需要进行调整!

SO网友:Jonas Lundman

无法评论,必须与其他版本一起发布。

问题:

如果Update 2) Set jpeg quality per image size name 在接受的答案是完整的。wp_get_additional_image_sizes() 返回global $_wp_additional_image_sizes 并且不包含有关默认大小(如中、大或缩略图)的任何信息。

这可能在筛选器中不起作用:“large”=>2

截至年月日https://codex.wordpress.org/Function_Reference/get_intermediate_image_sizes 使用自定义代码解释如何使用自定义函数检索所有大小。

我说得对吗?

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

具有相同“shop\\u product”设置的“medium”图像设置将仅作为其中之一“访问”此功能。然后,我们不知道过滤的是“中等”尺寸还是“shop\\u product”尺寸。因为,这里的目标只是图像的技术裁剪。

与的想法Update 2) 这是一种更具逻辑性的处理方式,但恐怕技术架构并不存在。在构建过滤器之前,分析所有注册图像大小,这将成为舒尔进一步发展的目标,使舒尔能够返回当前主题的正确质量图像程序。

具有相同设置的所有大小名称将共享相同的新质量,因为它们在服务器上共享相同的图像。

所以,如果你仍然坚持update 2) 我认为您需要调用另一个函数来填充$sizes 变量,并通过var\\u dump()分析$_wp_additional_image_sizes 用于相等设置。

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

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;
}

Developers attention

<在主题图像设置后应用Make shure滤波器is_admin() 然后,ajax调用、前端、远程发布的图像不会产生影响如前所述,裁剪值可以是0或false,您必须将(int)或(bool)转换为字符串$condition = ($crop ? \'true\' : \'false\');

Theme developers attention

WP默认压缩是非常渐进的。值介于8099 可能会带来巨大的差异or 根本没有可见的结果。无压缩值为100, 可能返回abigger filesize 关于“较小尺寸”800 px 图像,then 原来的大3000 px 已调整大小的版本。

多年后,我们发现了一个神奇的数字96,文件大小变小了,但你看不到100 值压缩。

高质量photoshop制作的商店图片,大于800px就可以了,Wordpress默认为82。但iPhone“大”电子邮件发布的图像在缩略图等小尺寸上确实需要96的值。在Wordpres压缩时,它们会变得“柔和模糊”。

如果您没有为您的项目、用户或主题规划方案,您将过度使用此主题解决方案。

A final reflexion

我真的很失望Wordpress,这个重要的问题在开发的优先考虑中被忽视了,因为图像比以往任何时候都更重要,是唯一有效的加载。

我们能不能在合适的地方安装一个过滤器,用于单独的压缩?他们不厌其烦地“更改名称”为wp\\U editor\\U set\\U quality,并且add_filter(\'jpeg_quality\' ... 现已弃用。为什么不一直思考这个问题,把if ( ! $this->quality ) 只检查一次@birgire提到的方法。

结束

相关推荐

Changing Gallery images size?

我正在抓取我的图库图像的URL:$gallery = get_post_gallery_images( $post ); foreach($gallery as $thumbnail) { echo $thumbnail_slideshow; } 问题是我得到的只是缩略图:image1-150x150.jpg image2-150x150.jpg image3-150x150.jpg 我想得到:image1-600x100.