Изменение размера и сохранения изображения

Я нашел и изменил размер изображения GD и сохранил коэффициент отношения, но он не работает должным образом.

Например, я хочу изменить размер изображения до MAXIMUM 200w x 200h. Изображение, которое я хочу изменить, - 518w x 691h, и сценарий должен изменить его размер до 150w x 200h, чтобы сохранить соотношение сторон, а вместо этого он изменил его размер до 200w x 226h. В чем проблема?

function resize_image($source_image, $name, $new_width, $new_height, $destination)
{
 list($source_image_width, $source_image_height, $source_image_type) = getimagesize($source_image);

 switch($source_image_type)
 {
 case IMAGETYPE_GIF:
 $source_gd_image = imagecreatefromgif($source_image);
 break;
 case IMAGETYPE_JPEG:
 $source_gd_image = imagecreatefromjpeg($source_image);
 break;
 case IMAGETYPE_PNG:
 $source_gd_image = imagecreatefrompng($source_image);
 break;
 }

 $source_aspect_ratio = $source_image_width / $source_image_height;
 $thumbnail_aspect_ratio = $new_width / new_height;

 if($source_image_width <= $new_width && $source_image_height <= new_height)
 {
 $thumbnail_image_width = $source_image_width;
 $thumbnail_image_height = $source_image_height;
 }
 elseif ($thumbnail_aspect_ratio > $source_aspect_ratio)
 {
 $thumbnail_image_width = (int)(new_height * $source_aspect_ratio);
 $thumbnail_image_height = new_height;
 }
 else
 {
 $thumbnail_image_width = $new_width;
 $thumbnail_image_height = (int)($new_width / $source_aspect_ratio);
 }

 $thumbnail_gd_image = imagecreatetruecolor($thumbnail_image_width, $thumbnail_image_height);


 imagealphablending($thumbnail_gd_image, false);
 imagesavealpha($thumbnail_gd_image, true);


 imagecopyresampled($thumbnail_gd_image, $source_gd_image, 0, 0, 0, 0, $thumbnail_image_width, $thumbnail_image_height, $source_image_width, $source_image_height);


 $destination = $destination.$name;

 switch($source_image_type)
 {
 case IMAGETYPE_GIF:
 imagegif($thumbnail_gd_image, $destination);
 break;
 case IMAGETYPE_JPEG:
 imagejpeg($thumbnail_gd_image, $destination, 100);
 break;
 case IMAGETYPE_PNG:
 imagepng($thumbnail_gd_image, $destination, 9);
 break;
 }


 imagedestroy($source_gd_image);
 imagedestroy($thumbnail_gd_image);
}
1 ответ

Эта секция:

elseif ($thumbnail_aspect_ratio > $source_aspect_ratio)

никогда не должен выполняться, так как вы хотите сохранить пропорции одинаковыми. Чтобы определить новую ширину/высоту, попробуйте что-то вроде этого:

if($width > $MAX_SIZE || $height > $MAX_SIZE) {
 $aspect = $width / $height;
 if($width > $height) {
 $width = $MAX_SIZE;
 $height = intval($MAX_SIZE / $aspect);
 } else {
 $height = $MAX_SIZE;
 $width = intval($MAX_SIZE * $aspect);
 }
}

Обновить

Весь этот код пытается определить новую ширину/высоту на основе ограничения $MAX_SIZE, сохраняя соотношение сторон одинаковым. Это не будет идеально, потому что арифметика с плавающей запятой редко бывает когда-либо (особенно потому, что в этом случае вы не можете иметь "дробные" пиксели, поэтому приведенные выше вычисления используют intval). Рассмотрим, например, до того, как этот код будет запущен $width, $height и $MAX_SIZE будут установлены следующим образом:

$MAX_SIZE = 100;
$width = 1920;
$height = 1080;

Исходное соотношение сторон - 1.77777777.... После выполнения вышеприведенного фрагмента ширина/высота будет установлена равной 100 x 56, что составляет соотношение 1,7857. Перемещение ширины/высоты вывода вверх или вниз с помощью пикселя никогда не даст вам точного соотношения входных форматов, если вы не позволяете пиксельным значениям с дробными компонентами.

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

licensed under cc by-sa 3.0 with attribution.