Qualité d'image en fonction de la taille de l'image

13

Est-il possible de définir la qualité de l'image en fonction de la taille de l'image? J'aimerais une meilleure qualité d'image pour les grandes images (80) - et pire pour les petites vignettes (30).

Je m'attendais à ce qu'un paramètre situé à add_size contrôle cela - mais il n'en existe aucun.

Si cela compte: j'utilise ImageMagick.

    
posée Nils Riedemann 21.03.2014 - 14:23

2 réponses

14

Le seul moment où vous définissez la qualité est vraiment important est juste avant que l'image soit enregistrée ou diffusée (pour l'éditeur). Le filtre "image_editor_save_pre" y est transmis à l’instance de l’éditeur d’image. Vous pouvez donc l'utiliser pour modifier l'image à votre guise, y compris pour régler la qualité.

Donc, quelque chose comme ceci devrait faire le travail simplement et facilement:

add_filter('image_editor_save_pre','example_adjust_quality');
function example_adjust_quality($image) {
    $size = $image->get_size();
    // Values are $size['width'] and $size['height']. Based on those, do what you like. Example:
    if ( $size['width'] <= 100 ) {
        $image->set_quality(30);
    }
    if ( $size['width'] > 100 && $size['width'] <= 300 ) {
        $image->set_quality(70);
    }
    if ( $size['width'] > 300 ) {
        $image->set_quality(80);
    }
    return $image;
}
    
réponse donnée Otto 26.03.2014 - 17:57
5

Note au début: La réponse ci-dessous n’est pas finie et n’a pas été testée, mais je n’ai pas assez de temps, alors je vais laisser cela ici comme brouillon. Ce qui nécessite probablement une deuxième paire d’œil est la méthode de qualité et l’interprétation de version_compare() .

Nous avons d’abord besoin d’un point d’entrée. Après avoir relu le faire un post , je pensais que le mieux serait de sauter avant qu'Editeur d'images enregistre la nouvelle image créée. Voici donc un microcontrôleur qui intercepte pendant un rappel relié à image_editor_save_pre et charge une classe qui examine ensuite les paramètres définis dans un rappel à wpse_jpeg_quality . Il renvoie simplement différents taux de compression pour le filtre jpeg_quality qui s'exécute dans l'éditeur d'images.

<?php

namespace WPSE;

/**
 * Plugin Name: (#138751) JPEG Quality Router
 * Author:      Franz Josef Kaiser
 * Author URI:  http://unserkaiser.com
 * License:     CC-BY-SA 2.5
 */

add_filter( 'image_editor_save_pre', 'WPSE\JPEGQualityController', 20, 2 );
/**
 * @param string $image
 * @param int $post_id
 * @return string
 */
function JPEGQualityController( $image, $post_id )
{
    $config = apply_filters( 'wpse_jpeg_quality', array(
        # Valid: <, lt, <=, le, >, gt, >=, ge, ==, =, eq
        'limit'      => 'gt',
        # Valid: h, w
        'reference'  => 'w',
        'breakpoint' => 50,

        'low'        => 80,
        'high'       => 100,
    ) );
    include_once plugin_dir_path( __FILE__ ).'worker.php';
    new \WPSE\JPEGQualityWorker( $image, $config );

    return $image;
}

Le travailleur réel est la classe JPEGQualityWorker . Il réside dans le même répertoire que le fichier de plug-in principal ci-dessus et s'appelle worker.php (ou vous modifiez le contrôleur ci-dessus).

Il récupère l'image et vos paramètres, puis ajoute des rappels au filtre jpeg_quality . Qu'est-ce qui est fait est

  • récupération de la référence de votre image (largeur ou hauteur)
  • interroger votre point d'arrêt qui décide où basculer entre le rapport qualité / compression basse et haute
  • récupération de la taille de l'image d'origine
  • décider de la qualité à retourner

Le point de rupture et la limite sont ce qui décide entre haut et bas et, comme mentionné ci-dessus, cela pourrait nécessiter plus d'amour.

<?php

namespace WPSE;

/**
 * Class JPEGQualityWorker
 * @package WPSE
 */
class JPEGQualityWorker
{
    protected $config, $image;
    /**
     * @param string $image
     * @param array $config
     */
    public function __construct( Array $config, $image )
    {
        $this->config = $config;
        $this->image  = $image;

        add_filter( 'jpeg_quality', array( $this, 'setQuality' ), 20, 2 );
    }

    /**
     * Return the JPEG compression ratio.
     *
     * Avoids running in multiple context, as WP runs the function multiple
     * times per resize/upload/edit task, which leads to over compressed images.
     *
     * @param int $compression
     * @param string $context Context: edit_image/image_resize/wp_crop_image
     * @return int
     */
    public function setQuality( $compression, $context )
    {
        if ( in_array( $context, array(
            'edit_image',
            'wp_crop_image',
        ) ) )
            return 100;

        $c = $this->getCompression( $this->config, $this->image );

        return ! is_wp_error( $c )
            ? $c
            : 100;
    }

    /**
     * @param array $config
     * @param string $image
     * @return int|string|\WP_Error
     */
    public function getCompression( Array $config, $image )
    {
        $reference = $this->getReference( $config );
        if ( is_wp_error( $reference ) )
            return $reference;
        $size = $this->getOriginalSize( $image, $reference );
        if ( is_wp_error( $size ) )
            return $size;

        return $this->getQuality( $config, $size );
    }

    /**
     * Returns the quality set for the current image size.
     * If
     * @param array $config
     * @param int $size
     */
    protected function getQuality( Array $config, $size )
    {
        $result = version_compare( $config['breakpoint'], $size );
        return (
            0 === $result
            AND in_array( $config['limit'], array( '>', 'gt', '>=', 'ge', '==', '=', 'eq' ) )
            ||
            1 === $result
            AND in_array( $config['limit'], array( '<', 'lt', '<=', 'le', ) )
        )
            ? $config['high']
            : $config['low'];
    }

    /**
     * Returns the reference size (width or height).
     *
     * @param array $config
     * @return string|\WP_Error
     */
    protected function getReference( Array $config )
    {
        $r = $config['reference'];
        return ! in_array( $r, array( 'w', 'h', ) )
            ? new \WP_Error(
                'wrong-arg',
                sprintf( 'Wrong argument for "reference" in %s', __METHOD__ )
            )
            : $r;
    }

    /**
     * Returns the size of the original image (width or height)
     * depending on the reference.
     *
     * @param string $image
     * @param string $reference
     * @return int|\WP_Error
     */
    protected function getOriginalSize( $image, $reference )
    {
        $size = 'h' === $reference
            ? imagesy( $image )
            : imagesx( $image );

        # @TODO Maybe check is_resource() to see if we got an image
        # @TODO Maybe check get_resource_type() for a valid image
        # @link http://www.php.net/manual/en/resource.php

        return ! $size
            ? new \WP_Error(
                'image-failure',
                sprintf( 'Resource failed in %s', get_class( $this ) )
            )
            : $size;
    }
}
    
réponse donnée kaiser 21.03.2014 - 17:57

Lire d'autres questions sur les étiquettes