Um filtro muito especial
O jpeg_quality
filtro é realmente especial: é usado em três casos diferentes e você deve usar o segundo argumento para determinar se deseja ou não usar o filtro.
Não deixe fazer tudo
O principal problema desse filtro especial é que ele pode ser acionado para ações posteriores, se você não o remover - permita que ele seja executado após a primeira verificação. Portanto, precisamos inserir outro filtro wp_save_image_file()
para verificar se queremos alterar a compactação ou não. Para desativá-lo para outro processo de salvamento, nós o removemos antes de alterar a compactação.
O garoto kool
O mais estranho é que o WP usa uma compactação padrão de 90% (que é 10% de qualidade reduzida) para cada processo de salvamento. Isso significa que, toda vez que você faz upload / recorta / edita uma imagem, reduz a qualidade ... o que é uma dor para as imagens que não são as melhores quando você faz o upload delas (teste-a com uma imagem contendo muito vermelho com um fundo de alto contraste). Mas ... O mais interessante é que você pode mudar esse comportamento. Então, você deseja alterar a compactação, mas obter maior qualidade - muito melhor do que o núcleo permite - ao mesmo tempo.
/**
* 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 );
EDIT: Após uma breve discussão com @toscho, ele apontou que todo o retorno de chamada poderia ser reduzido para o seguinte:
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;
}
Como retirei o código de um plug-in no qual estou trabalhando, eu precisava switch
adicionar configurações. Também tenho que observar que não uso o global
plug-in, pois é uma abordagem OOP. O código que você pode ler ↑ acima, é principalmente código reduzido e alterado do plug-in, que tem algumas sobras menores e serve para explicar os leitores posteriores e ainda funciona. Se você quiser usá-lo como plug-in, poderá fazer alguma otimização dependendo do seu caso de uso pessoal.
Notas:
De alguma investigação sobre as diferentes tarefas, notei que vários $case
s são acionados nas seguintes etapas:
- Girar:
edit-image
» image-resize
(o último 1 × para qualquer tamanho que você escolher - miniatura, etc.)
- Espelho:
edit-image
» image-resize
(-" -)
Isso significa que o retorno de chamada do filtro jpeq_quality
acionará 2 × para girar / espelhar uma imagem e + 1 × para qualquer tamanho adicional que você adicionar. Portanto, se você tiver menos de 100%, a qualidade será reduzida duas vezes. Pesquisei bastante sobre esse assunto, mas ainda não tenho certeza de quais funções exatas causam esse comportamento.
echo '<pre>'.var_export( $image, true ).'</pre>';
. Coloque umexit;
depois dele, para que ele não fique ignorado com recarregar a página, etc.wpse58600_custom_jpg_compression()
função.