Измените размер изображения и обрежьте его до нового соотношения сторон

С помощью этого кода загружаемые изображения уменьшаются в размере, чтобы соответствовать установленному максимальному размеру, сохраняя исходное соотношение сторон. Это прекрасно работает.

Теперь я стремлюсь к тому, чтобы он также обрезал изображение, поэтому оно меняет соотношение сторон на 4: 3 (горизонтальное / вертикальное). Также в пределах максимального размера 800 пикселей в любом случае.

Я пробовал различные коды/идеи, которые мог найти в сети, но они, похоже, искажали изображение, только обрезали или вообще не работали. Как можно включить обрезку аспекта в код, который у меня уже есть?

$max_width = 800;
$max_height = 800;

$image_size_info = getimagesize($image_temp);
$image_width = $image_size_info[0];
$image_height = $image_size_info[1];

$image_res = imagecreatefromjpeg($image_temp);

$image_scale = min($max_width/$image_width, $max_height/$image_height);
$new_width = ceil($image_scale * $image_width);
$new_height = ceil($image_scale * $image_height);

$canvas = imagecreatetruecolor($new_width, $new_height);

imagecopyresampled($canvas, $image_res, 0, 0, 0, 0, $new_width, $new_height, $image_width, $image_height);

imagejpeg($canvas, 'images/image.jpg', 85);

imagedestroy($image_res);

PS: Пожалуйста, вопрос именно об ЭТОМ коде


person mowgli    schedule 26.07.2015    source источник
comment
вы можете попробовать облачный cloudinary.com API, вы можете размещать фотографии, и они имеют очень хороший масштаб | аспект и многие другие хорошие инструменты   -  person Daniel Krom    schedule 27.07.2015
comment
Спасибо, но нет. Я буду придерживаться этого чрезвычайно простого и локального способа. Я приближаюсь к цели сейчас   -  person mowgli    schedule 27.07.2015
comment
да, я понимаю, я был слишком ленив, когда у меня была такая же проблема @mowgli   -  person Daniel Krom    schedule 27.07.2015


Ответы (2)


После долгих возни это работает.

Он изменяет размер и кадрирует, поэтому изображения становятся либо 4:3, либо 3:4, в зависимости от преобладающей начальной ширины/высоты.

При использовании очень маленьких изображений также должна быть некоторая проверка и/или обход, чтобы они не масштабировались и т. д.

$max_width = 800;
$max_height = 800;

$image_size_info = getimagesize($image_temp);
$image_width = $image_size_info[0];
$image_height = $image_size_info[1];

$image_res = imagecreatefromjpeg($image_temp);

if ($image_height < $image_width) {

    $cropfactor = $image_height / $image_width;
    $cropfactor = ($cropfactor > 0.75) ? $cropfactor : 0.75;
    $max_height = ceil($max_height * $cropfactor);

} elseif ($image_width < $image_height) {

    $cropfactor = $image_width / $image_height;
    $cropfactor = ($cropfactor > 0.75) ? $cropfactor : 0.75;
    $max_width = ceil($max_width * $cropfactor);

}

$new_width = $image_height * $max_width / $max_height;
$new_height = $image_width * $max_height / $max_width;

$canvas = imagecreatetruecolor($max_width, $max_height);

if ($new_width > $image_width) {

   $cut_x = 0;
   $cut_y = (($image_height - $new_height) / 2);
   $new_width_canvas = $image_width;
   $new_height_canvas = $new_height;

} else {

   $cut_x = (($image_width - $new_width) / 2);
   $cut_y = 0;
   $new_width_canvas = $new_width;
   $new_height_canvas = $image_height;

}

imagecopyresampled($canvas, $image_res, 0, 0, $cut_x, $cut_y, $max_width, $max_height, $new_width_canvas, $new_height_canvas);

imagejpeg($canvas, 'images/image.jpg', 85);

imagedestroy($image_res);
person mowgli    schedule 27.07.2015

Не уверен, используете ли вы его на общем сервере или на каком-то управляемом или выделенном сервере, но imagemagick — действительно удобный инструмент для всех этих задач.

person Lund    schedule 26.07.2015
comment
Да, я слышал об этом. Но я уже так близок к цели с тем, что у меня есть, что лучше просто придерживаться этого. Так вот о чем мой вопрос - person mowgli; 26.07.2015
comment
Вы уже пробовали функцию imagecrop в PHP (›5.5)? php.net/manual/de/function.imagecrop.php - person Lund; 26.07.2015
comment
Нет, но это, похоже, только обрезка, а не изменение размера. И я уверен, что смогу получить передискретизацию изображения, чтобы выполнить его нормально, с правильными вычислениями. Я уже обрезаю для миниатюры слишком хорошо. Поэтому мне просто нужен правильный алгоритм/расчет для обрезки аспектов. О, и на сервере работает php 5.4 - person mowgli; 26.07.2015