Ajouter une taille d'image où la plus grande taille proportionnelle possible est générée

8

Je voudrais ajouter une taille d'image où l'image résultante sera la plus grande taille possible tout en conservant un rapport d'aspect 4: 3.

Supposons que j'ai ajouté une taille d'image comme ceci:

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

Par défaut, WP ne crée une image avec cette taille que si l'image pleine taille est plus grande que ces dimensions.

Mais supposons que mon image en taille réelle ne fasse que 1000 pixels de large. Je voudrais quand même avoir une image recadrée au plus grand rapport possible 4: 3, qui dans ce cas serait 1000x750.

Cela peut-il être fait?

Chris Montgomery
la source

Réponses:

11

L'approche

Je pense que la meilleure approche consiste à créer une taille d'image "à la volée", juste avant le redimensionnement des images.

Vous pouvez le faire en utilisant un 'intermediate_image_sizes_advanced'crochet de filtre. Cela vous permet de modifier la taille à générer, mais en étant conscient de la taille de l'image actuelle, qui est stockée dans le tableau $metadatapassé par le filtre comme deuxième argument.

Les maths

Écrivons tout d'abord une classe qui renvoie les plus grandes tailles pour un rapport spécifique.

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

}

Utilisation des cours

L'utilisation de la classe est assez simple:

$ratio = new ImageRatio(4, 3)

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

En action

À ce stade, nous pouvons utiliser la classe pour calculer à la volée une nouvelle taille d'images, en fonction de l'image en cours de téléchargement

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

Utilisation de la nouvelle taille

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

Remarque

Bien sûr, cela fonctionne pour toutes les images que vous téléchargez une fois le code en place. Pour les images plus anciennes, vous devez recréer les miniatures, à la volée lorsqu'elles sont utilisées, ou en masse en utilisant l'un des plugins disponibles sur le Web.

gmazzap
la source
Cela fonctionne très bien, merci! Une correction mineure que je ferais: je pense qu'il n'est pas nécessaire de définir un ratio par défaut dans le constructeur, car je pourrais l'utiliser pour d'autres ratios à l'avenir. Il est logique de toujours fournir le rapport souhaité lors de l'instanciation.
Chris Montgomery
Les arguments dans le constructeur sont juste par défaut. Vous pouvez passer n'importe quel ratio que vous voulez, les
valeurs