Agregar tamaño de imagen donde se genera el mayor tamaño proporcional posible

8

Me gustaría agregar un tamaño de imagen donde la imagen resultante sea el tamaño más grande posible mientras se mantiene una relación de aspecto de 4: 3.

Supongamos que he agregado un tamaño de imagen así:

add_image_size( 'cover-image', 2048, 1536, true );

De manera predeterminada, WP solo creará una imagen con ese tamaño si la imagen de tamaño completo es más grande que esas dimensiones.

Pero supongamos que mi imagen de tamaño completo tiene solo 1000 px de ancho. Todavía me gustaría tener una imagen recortada a la relación 4: 3 más grande posible, que en este caso sería 1000x750.

Se puede hacer esto?

Chris Montgomery
fuente

Respuestas:

11

El enfoque

Creo que el mejor enfoque es crear un tamaño de imagen "sobre la marcha", justo antes de cambiar el tamaño de las imágenes.

Puede hacerlo usando el 'intermediate_image_sizes_advanced'gancho de filtro. Eso le permite editar el tamaño que se generará, pero teniendo en cuenta el tamaño de la imagen actual, que se almacena en la matriz que $metadatapasa el filtro como segundo argumento.

Las matemáticas

En primer lugar, escriba una clase que devuelva los tamaños más grandes para una relación específica.

class ImageRatio {

  private $ratio;

  function __construct($ratioW = 4, $ratioH = 3) {
    $this->ratio = array($ratioW, $ratioH);
  }

  function getLargestSize($imgW, $imgH) {
    $inverse = false;
    // let's try to keep width and calculate new height  
    $newSize = round(($this->ratio[1] * $imgW) / $this->ratio[0]);
    if ($newSize > $imgH) {
       $inverse = true;
       // if the calculated height is bigger than actual size
       // let's keep current height and calculate new width
       $newSize = round(($this->ratio[0] * $imgH) / $this->ratio[1]);
    }

    return $inverse ? array( $newSize, $imgH ) : array( $imgW, $newSize );
  }

}

Uso de la clase

El uso de la clase es bastante fácil:

$ratio = new ImageRatio(4, 3)

$ratio->getLargestSize(1000, 500); // return: array(667, 500)
$ratio->getLargestSize(1000, 800); // return: array(1000, 750)

En acción

En este punto, podemos hacer uso de la clase para calcular sobre la marcha un nuevo tamaño de imágenes, en función de la imagen que se está cargando

add_filter( 'intermediate_image_sizes_advanced', function( $sizes, $metadata ) {

   if (! empty( $metadata['width'] ) && ! empty( $metadata['height'] ) ) {
      // calculate the max width and height for the ratio
      $ratio = new ImageRatio( 4, 3 );
      list($width, $height) = $ratio->getLargestSize( 
         $metadata['width'],
         $metadata['height']
      );
      // let's add our custom size
      $sizes['biggest-4-3'] = array(
        'width'  => $width,
        'height' => $height,
        'crop'   => true
      );
   }

   return $sizes;

}, 10, 2 );

Usando el nuevo tamaño

$image = wp_get_attachment_image( $attachment_id, 'biggest-4-3' );

Nota

Por supuesto, esto funciona para todas las imágenes que cargue después de que el código esté en su lugar. Para las imágenes más antiguas, debe volver a generar las miniaturas, sobre la marcha cuando se utilizan, o en bloque utilizando uno de los complementos disponibles en la web.

gmazzap
fuente
Esto funciona muy bien, gracias! Una pequeña corrección que haría: creo que no es necesario establecer una relación predeterminada en el constructor, ya que podría usar esto para otras relaciones en el futuro. Tiene sentido suministrar siempre la proporción deseada en la instanciación.
Chris Montgomery
Los argumentos en el constructor son por defecto. Puede pasar cualquier proporción que desee, los
valores