Подход
Я думаю, что лучший подход - это создать размер изображения «на лету», непосредственно перед изменением размера изображения.
Вы можете сделать это, используя 'intermediate_image_sizes_advanced'
фильтр Hook. Это позволяет вам редактировать размер, который будет сгенерирован, но с учетом текущего размера изображения, который сохраняется в массиве, $metadata
передаваемом фильтром в качестве второго аргумента.
Математика
Прежде всего давайте напишем класс, который возвращает самые большие размеры для определенного соотношения.
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 );
}
}
Использование класса
Использование класса довольно просто:
$ratio = new ImageRatio(4, 3)
$ratio->getLargestSize(1000, 500); // return: array(667, 500)
$ratio->getLargestSize(1000, 800); // return: array(1000, 750)
В действии
На этом этапе мы можем использовать класс для вычисления на лету нового размера изображения, основываясь на загружаемом изображении.
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 );
Используя новый размер
$image = wp_get_attachment_image( $attachment_id, 'biggest-4-3' );
Запись
Конечно, это работает для всех изображений, которые вы загружаете после установки кода. Для старых изображений вы должны заново сгенерировать миниатюры, на лету, когда они используются, или навалом, используя один из плагинов, доступных в Интернете.