Очень специальный фильтр
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
в своем плагине, так как это ООП подход. Код, который вы можете прочитать выше, в основном сокращен и изменен из плагина, который имеет некоторые незначительные остатки и предназначен для пояснения для более поздних читателей и все еще работает. Если вы хотите использовать его как плагин, вы можете провести некоторую оптимизацию в зависимости от вашего личного использования.
Ноты:
Из некоторых исследований различных задач я заметил, что множественные $case
s запускаются на следующих шагах:
- Повернуть:
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()
функции.