Modifica della compressione JPEG in base alla dimensione dell'immagine


8

Corto. Voglio che le immagini "grandi" siano compresse del 90% e che "medio" sia del 60%. Ha molte af che conosci, a volte le immagini più grandi soffrono di alta compressione, ma altre piccole immagini no.

Questa funzione consente di ricampionare tutte le immagini jpg

function custom_jpg_compression($args) {
    return 90;
}
add_filter('jpeg_quality', 'custom_jpg_compression');

Come filtrare per dimensione dell'immagine?

Risposte:


11

Un filtro molto speciale

Il jpeg_qualityfiltro è davvero speciale: viene utilizzato in tre casi diversi e devi usare il secondo argomento per determinare se vuoi usare il filtro o meno.

Non lasciarlo fare tutto

Il problema principale per un filtro così speciale è che potrebbe attivarsi per le azioni successive, se non lo si rimuove: consentirne l'esecuzione dopo il primo controllo. Quindi dobbiamo inserire un altro filtro wp_save_image_file()per verificare se vogliamo modificare la compressione o meno. Per disabilitarlo per un altro processo di salvataggio, lo rimuoviamo subito prima di modificare la compressione.

Il ragazzo kool

La cosa davvero strana è che WP utilizza una compressione predefinita del 90% (che è una qualità ridotta del 10%) per ogni processo di salvataggio. Ciò significa che ogni volta che carichi / ritaglia / modifichi un'immagine, ne riduci la qualità ... il che è un dolore per le immagini che non sono le migliori, quando le carichi (testale con un'immagine che contiene molto rosso con uno sfondo ad alto contrasto). Ma ... La cosa davvero bella è che puoi cambiare questo comportamento. Quindi vuoi cambiare la compressione, ma ottenere una maggiore qualità - molto meglio di quanto consente il core - allo stesso 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: Dopo una breve discussione con @toscho, ha sottolineato che l'intero callback potrebbe essere ridotto al seguente:

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;
}

Mentre estraevo il codice da un plug-in su cui sto attualmente lavorando, avevo bisogno switchdi aggiungere le impostazioni. Devo anche notare che non uso il globalmio plug-in, in quanto è un approccio OOP. Il codice che puoi leggere ↑ in alto, è principalmente ridotto e modificato dal plug-in, che ha alcuni piccoli avanzi ed è pensato per essere esplicativo per i lettori successivi e funziona ancora. Se si desidera utilizzarlo come plug-in, è possibile eseguire alcune ottimizzazioni a seconda del proprio caso d'uso personale.


Appunti:

Da alcune indagini sui diversi compiti, ho notato che più $cases vengono attivati ​​nei seguenti passaggi:

  • Ruota: edit-image» image-resize(il 1 × successivo per qualsiasi dimensione tu scelga - Miniatura, ecc.)
  • Specchio: edit-image» image-resize(-" -)

Ciò significa che il callback del filtro per jpeq_qualityattiverà 2 × per ruotare / rispecchiare un'immagine e + 1 × per qualsiasi dimensione aggiuntiva aggiunta. Quindi se hai meno del 100%, ridurrà la qualità due volte. Ho fatto molte ricerche su questo argomento, ma non sono ancora del tutto sicuro di quali funzioni esatte causino questo comportamento.


Ups mi hai preso, print_r / var_dump non funziona. Come posso emetterlo?
DarkGhostHunter il

Usa echo '<pre>'.var_export( $image, true ).'</pre>';. Mettilo exit;dopo, in modo che non venga ignorato ricaricando la pagina, ecc.
Kaiser

accidenti, perso nei boschi - non riesco a vedere dove stampa. Ho quel codice prima dell'immagine di ritorno $;
DarkGhostHunter il

Aggiungilo all'inizio della wpse58600_custom_jpg_compression()funzione.
Kaiser,

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.