Un filtro muy especial
El jpeg_quality
filtro es realmente especial: se usa en tres casos diferentes y debe usar el segundo argumento para determinar si desea usar el filtro o no.
No dejes que haga todo
El principal problema para un filtro tan especial es que puede activarse para acciones posteriores, si no lo elimina, permita que se ejecute después de la primera verificación. Por lo tanto, necesitamos otro filtro wp_save_image_file()
para verificar si queremos alterar la compresión o no. Para deshabilitarlo para otro proceso de guardado, lo eliminamos justo antes de alterar la compresión.
El niño kool
Lo realmente extraño es que WP utiliza una compresión predeterminada del 90% (que es un 10% de calidad reducida) para cada proceso de guardado. Esto significa que cada vez que carga / recorta / edita una imagen, reduce su calidad ... lo cual es un dolor para las imágenes que no son las mejores, cuando las carga (pruébelo con una imagen que contenga mucho rojo). con un fondo de alto contraste). Pero ... Lo realmente bueno es que puedes cambiar este comportamiento. Por lo tanto, desea cambiar la compresión, pero obtener una mayor calidad , mucho mejor de lo que permite el núcleo, al mismo tiempo.
/**
* 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 );
EDITAR: Después de una breve discusión con @toscho, señaló, que toda la devolución de llamada podría reducirse a lo siguiente:
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;
}
Cuando saqué el código de un complemento en el que estoy trabajando actualmente, necesitaba switch
agregar la configuración. También tengo que tener en cuenta que no uso el global
en mi complemento, ya que es un enfoque OOP. El código que puede leer ↑ arriba, es principalmente un código reducido y alterado del complemento, que tiene algunos sobrantes menores y está destinado a ser explicativo para lectores posteriores y aún funciona. Si desea usarlo como complemento, puede hacer alguna optimización dependiendo de su caso de uso personal.
Notas:
De alguna investigación sobre las diferentes tareas, hay, noté, que $case
se activan múltiples s en los siguientes pasos:
- Rotar:
edit-image
» image-resize
(el último 1 × para cualquier tamaño que elija - Miniatura, etc.)
- Espejo:
edit-image
» image-resize
(-" -)
Esto significa que la devolución de llamada del filtro jpeq_quality
activará 2 × para girar / reflejar una imagen y + 1 × para cualquier tamaño adicional que agregue. Entonces, si obtuvo menos del 100%, reducirá la calidad dos veces. Investigué mucho sobre este tema, pero todavía no estoy completamente seguro de qué funciones exactas causan este comportamiento.