Calidad de imagen basada en el tamaño de la imagen

13

¿Es posible configurar la calidad de la imagen según el tamaño de la imagen? Me gustaría tener una mejor calidad de imagen para imágenes más grandes (80), y peor para miniaturas pequeñas (30).

Estaba esperando un parámetro en add_size para controlar eso, pero no hay ninguno.

Si importa: estoy usando ImageMagick.

    
pregunta Nils Riedemann 21.03.2014 - 14:23

2 respuestas

14

La única vez que se configura la calidad realmente es justo antes de guardar o transmitir la imagen (para el editor). Ambos tienen el filtro "image_editor_save_pre" allí, pasándole la instancia del editor de imágenes. Así que puedes usarlo para modificar la imagen de la forma que desees, incluida la configuración de la calidad.

Entonces, algo como esto debería hacer el trabajo simple y fácilmente:

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;
}
    
respondido por el Otto 26.03.2014 - 17:57
5

Nota inicial: debajo de la respuesta no está terminada ni probada, pero no me queda tiempo suficiente, así que dejaré esto aquí como borrador. Lo que probablemente necesite un segundo par de ojos es el método de calidad y la interpretación de version_compare() .

Primero necesitamos un punto de entrada. Después de leer nuevamente make post , pensé que lo mejor sería saltar antes de que el Editor de imágenes guarde la imagen recién creada. Entonces, aquí hay un microcontrolador que intercepta durante una devolución de llamada enganchada a image_editor_save_pre y carga una clase que luego recorre sus configuraciones definidas dentro de una devolución de llamada a wpse_jpeg_quality . Simplemente devuelve diferentes índices de compresión para el filtro jpeg_quality que se ejecuta dentro del Editor de imágenes.

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

El trabajador real es la clase JPEGQualityWorker . Se encuentra en el mismo directorio que el archivo principal del complemento anterior y se llama worker.php (o si cambia el controlador anterior).

Recupera la imagen y su configuración y luego agrega devoluciones de llamada al filtro jpeg_quality . Lo que se hace es

  • recuperar su referencia de imagen (ancho o alto)
  • cuestionando su punto de interrupción que decide dónde cambiar entre una relación de compresión / calidad baja y alta
  • recuperando el tamaño de la imagen original
  • decidir qué calidad devolver

El punto de interrupción y el límite es lo que decide entre alto y bajo y, como se mencionó anteriormente, esto podría necesitar más amor.

<?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;
    }
}
    
respondido por el kaiser 21.03.2014 - 17:57

Lea otras preguntas en las etiquetas