Ein ganz besonderer Filter
Der jpeg_quality
Filter ist ein ganz besonderer: Er wird in drei verschiedenen Fällen verwendet und Sie müssen das zweite Argument verwenden, um zu bestimmen, ob Sie den Filter verwenden möchten oder nicht.
Lass es nicht alles machen
Das Hauptproblem für einen solchen speziellen Filter besteht darin, dass er möglicherweise für spätere Aktionen ausgelöst wird, wenn Sie ihn nicht entfernen. Lassen Sie ihn nach der ersten Überprüfung laufen. Wir müssen also einen weiteren Filter einbauen wp_save_image_file()
, um zu überprüfen, ob wir die Komprimierung ändern möchten oder nicht. Um es für einen anderen Speichervorgang zu deaktivieren, entfernen wir es unmittelbar vor dem Ändern der Komprimierung.
Das coole Kind
Das wirklich Seltsame ist, dass WP für jeden Speichervorgang eine Standardkomprimierung von 90% (was einer um 10% reduzierten Qualität entspricht) verwendet. Dies bedeutet, dass Sie jedes Mal, wenn Sie ein Bild hochladen / zuschneiden / bearbeiten, dessen Qualität verringern. Dies ist ein Schmerz für Bilder, die beim Hochladen nicht die besten sind (testen Sie es mit einem Bild, das viel Rot enthält mit kontrastreichem Hintergrund). Aber ... Das wirklich nette ist, dass Sie dieses Verhalten ändern können. Sie möchten also die Komprimierung ändern, aber gleichzeitig eine höhere Qualität erzielen - viel besser als es der Kern zulässt.
/**
* 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: Nach einer kurzen Diskussion mit @toscho wies er darauf hin, dass der gesamte Rückruf auf Folgendes reduziert werden könne:
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;
}
Da ich den Code aus einem Plugin gezogen habe, an dem ich gerade arbeite, musste ich die switch
Einstellungen hinzufügen. Ich muss auch beachten, dass ich den global
in meinem Plugin nicht verwende , da es sich um einen OOP-Ansatz handelt. Der Code, den Sie oben ↑ lesen können, ist hauptsächlich reduzierter und geänderter Code aus dem Plugin, der einige kleinere Reste enthält und für spätere Leser erklärend sein soll und immer noch funktioniert. Wenn Sie es als Plugin verwenden möchten, können Sie je nach Ihrem persönlichen Anwendungsfall einige Optimierungen vornehmen.
Anmerkungen:
Bei einigen Untersuchungen zu den verschiedenen Aufgaben habe ich festgestellt, dass $case
bei den folgenden Schritten mehrere s ausgelöst werden:
- Drehen:
edit-image
» image-resize
(das spätere 1 × für jede von Ihnen gewählte Größe - Miniaturbild usw.)
- Spiegel:
edit-image
» image-resize
(-" -)
Dies bedeutet, dass der Filterrückruf für jpeq_quality
2 × zum Drehen / Spiegeln eines Bildes und + 1 × für jede zusätzliche Größe, die Sie hinzufügen, ausgelöst wird. Wenn Sie also weniger als 100% erhalten, wird die Qualität zweimal reduziert. Ich habe viel zu diesem Thema recherchiert, bin mir aber immer noch nicht ganz sicher, welche genauen Funktionen dieses Verhalten verursachen.