Fügen Sie die Bildgröße hinzu, wenn die größtmögliche proportionale Größe generiert wird

8

Ich möchte eine Bildgröße hinzufügen, bei der das resultierende Bild die größtmögliche Größe hat, während das Seitenverhältnis 4: 3 beibehalten wird.

Angenommen, ich habe eine Bildgröße wie folgt hinzugefügt:

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

Standardmäßig erstellt WP nur dann ein Bild mit dieser Größe, wenn das Bild in voller Größe größer als diese Abmessungen ist.

Angenommen, mein Bild in voller Größe ist nur 1000 Pixel breit. Ich hätte immer noch gerne ein Bild, das auf das größtmögliche Verhältnis von 4: 3 zugeschnitten ist, in diesem Fall 1000 x 750.

Kann das gemacht werden?

Chris Montgomery
quelle

Antworten:

11

Die Vorgehensweise

Ich denke, der beste Ansatz ist es, eine Bildgröße "on the fly" zu erstellen, kurz bevor die Größe der Bilder geändert wird.

Sie können dies mit einem 'intermediate_image_sizes_advanced'Filterhaken tun . Auf diese Weise können Sie die zu generierende Größe bearbeiten, wobei Sie jedoch die aktuelle Bildgröße berücksichtigen, die in dem $metadatavom Filter als zweites Argument übergebenen Array gespeichert ist .

Die Mathematik

Schreiben wir zunächst eine Klasse, die die größten Größen für ein bestimmtes Verhältnis zurückgibt.

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

}

Klassengebrauch

Die Verwendung der Klasse ist ziemlich einfach:

$ratio = new ImageRatio(4, 3)

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

In Aktion

An diesem Punkt können wir die Klasse verwenden, um im laufenden Betrieb eine neue Bildgröße zu berechnen, die auf dem hochgeladenen Bild basiert

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

Verwenden der neuen Größe

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

Hinweis

Dies funktioniert natürlich für alle Bilder, die Sie hochladen, nachdem der Code vorhanden ist. Bei älteren Bildern sollten Sie die Miniaturansichten sofort, wenn sie verwendet werden, oder in großen Mengen mithilfe eines der im Web verfügbaren Plugins neu generieren.

gmazzap
quelle
Das funktioniert super, danke! Eine kleine Korrektur, die ich vornehmen würde: Ich denke, es ist nicht notwendig, ein Standardverhältnis im Konstruktor festzulegen, da ich dieses in Zukunft möglicherweise für andere Verhältnisse verwenden werde. Es ist sinnvoll, bei der Instanziierung immer das gewünschte Verhältnis anzugeben.
Chris Montgomery
Die Argumente im Konstruktor sind nur Standard. Sie können jedes gewünschte Verhältnis übergeben. Die Standardeinstellung wird nur verwendet, wenn Sie nichts übergeben
gmazzap