Answers:
jpeg_quality
过滤器是一个非常特殊的过滤器:它在三种不同的情况下使用,您必须使用第二个参数来确定是否要使用过滤器。
这种特殊过滤器的主要问题是,如果您不删除它,它可能会在以后的操作中触发-允许它在第一次检查后运行。因此,我们需要在内部wp_save_image_file()
添加另一个过滤器,以检查是否要更改压缩率。要在其他保存过程中将其禁用,我们将在更改压缩之前将其删除。
真正奇怪的是,WP为每个保存过程使用默认压缩90%(质量降低10%)。这意味着,每次上传/裁剪/编辑图像时,都会降低图像的质量...这对于并非最佳图像的痛苦是当您上传它们时(用包含大量红色的图像进行测试)具有高对比度的背景)。但是 ……真正的巧妙之处在于,您可以更改此行为。因此,您想更改压缩率,但同时要获得更高的质量 -比内核允许的质量好得多。
/**
* Alter the image compression, depending on case
*
* @param int $compression
* @param string $case
* @return int $compression
*/
function wpse58600_custom_jpg_compression_cb( $compression, $case )
{
global $size_switch;
// Should only fire once - don't leave it in for later cases
remove_filter( current_filter(), __FUNCTION__ );
// Alter the compression, depending on the case
switch ( $case )
{
case( 'edit_image' ) :
// We only add the compression, if the switch triggered,
// which means, that the size is smaller, than set in the main function.
// 60 is the percentage value, that gets added as compression to the smaller images.
$compression = $size_switch ? 60 : 100;
break;
case( 'image_resize' ) :
// Better leave it on 100% for resize
$compression = 100;
break;
case( 'wp_crop_image' ) :
// Better leave it on 100% for crop
// We already compressed it on the camera, the desktop/handheld device
// and the server previously. That's enough so far.
$compression = 100;
break;
}
return $compression;
}
/**
* Alter the compression for JPEG mime type images
* Checks for a specific min size of the image, before altering it
*
* @param string $image
* @param int $post_id
* @return string $image
*/
function wpse58600_custom_jpg_compression( $image, $post_id )
{
global $size_switch;
$size_switch = false;
// Define the size, that stops adding a compression
$trigger_size = 641;
// Get the sizes
$size_x = imagesx( $image );
$size_y = imagesy( $image );
// Add the filter only in case
if ( $trigger_size < $size_x )
{
$size_switch = true;
}
add_filter( 'jpeg_quality', 'wpse58600_custom_jpg_compression_cb', 20, 2 );
return $image;
}
add_filter( 'image_save_pre', 'wpse58600_custom_jpg_compression', 20, 2 );
编辑:在与@toscho简短讨论之后,他指出,整个回调可以简化为以下内容:
function wpse58600_custom_jpg_compression_cb( $compression, $case )
{
// Should only fire once - don't leave it in for later cases
remove_filter( current_filter(), __FUNCTION__ );
return ( $GLOBALS['size_switch'] && 'edit_image' === $case ) ? 60 : 100;
}
当我从当前正在使用的插件中取出代码时,我需要在其中switch
添加设置。我还必须注意,我不在global
插件中使用,因为这是一种OOP方法。您可以在上面的↑中阅读的代码,主要是该插件中经过简化和更改的代码,其中还有少量遗留之处,旨在为以后的读者提供解释,并且仍然可以使用。如果您想将其用作插件,则可以根据个人用例进行一些优化。
通过对不同任务的调查,我注意到,$case
在以下步骤中触发了多个:
edit-image
» image-resize
(对于您选择的任何大小,后1倍-缩略图等)edit-image
» image-resize
(-“-)这意味着,用于的过滤器回调jpeq_quality
将触发2倍旋转/镜像图像,而+1倍增加您添加的其他尺寸。因此,如果您获得的质量少于100%,则会降低质量两次。我对此主题进行了很多研究,但是我仍然不确定到底是什么确切的功能导致了这种现象。
echo '<pre>'.var_export( $image, true ).'</pre>';
。把一个exit;
经过它,所以它不会跳过与重新加载页面等
wpse58600_custom_jpg_compression()
函数的开头。