Изменение размера панорамного изображения на фиксированный размер

Я хочу изменить размеры изображений на фиксированную ширину и высоту (то есть 150 пикселей). Тем не менее, проблема возникает, если есть большая разница в высоте и ширине исходной фотографии (например, панорамная фотография), уменьшенный размер миниатюры выглядит плохо. Есть ли какое-нибудь умное решение для изменения размера фотографий до фиксированной ширины и высоты? Например, пожалуйста, взгляните на это изображение: введите описание изображения здесь

Вот мой код:

<?php $params = getimagesize($tempFile); $width = $params[0]; $height = $params[1]; $newwidth=150; $newheight= 150; $tmp=imagecreatetruecolor($newwidth,$newheight); imagecopyresampled($tmp,$src,0,0,0,0,$newwidth,$newheight,$width,$height); imagejpeg($tmp,$img_name,80); imagedestroy($src); imagedestroy($tmp); ?> 

Есть ли какой-либо умный способ изменить размер изображений с помощью смарт-образа? Благодарю.

Есть интеллектуальное решение, это называется Seam Carving , и если ваш сервер поддерживает ImageMagick, вы делаете это так:

 <?php $im = new Imagick( 'image.jpg' ); $im->liquidRescaleImage( 600, 100, 3, 25 ); header( 'Content-Type: image/jpg' ); echo $im; ?> 

Или, в противном случае, если это не поддерживается, используйте exec () ( тщательно ), чтобы передать изображение в качестве аргумента в исполняемый файл, который может выполнять резьбу по швам.

Кстати, это выглядит как twitpic, только что вырезанный фрагмент изображения. В одном из моих предыдущих проектов я использовал следующий код:

 if ($image->width > $image->height){ //crop image in proportions 4/3, then resize to 500x300 (or proportionally lower resolution), //sharp it a little and decrease quality. //I used one of the Yii framework extensions. $image->crop($image->width, $image->width/4*3)->resize(500, 300, Image::WIDTH)->sharpen(15)->quality(75); } 

Похоже, что twitpic выясняет, как долго короткая ось, затем берет квадрат с центром по исходному изображению со сторонами, равными длине короткой оси, а затем уменьшая это до 150×150.

Не, resmaple, получить только центр 150×150 пикселей.

Вам нужно будет вычислить соответствующие координаты для исходной области, которую вы хотите скопировать:

 imagecopyresampled($tmp,$src,0,0,[THIS VALUE],[THIS VALUE],$newwidth,$newheight, [THIS VALUE],[THIS VALUE]); 

На данный момент вы берете область от 0,0 (x, y) до ширины, высоты (x, y) исходной области и пытаетесь сузить ее до 150×150.

вам нужно будет вычислить, какая из ширины и высоты является «самой большой» и обрезать, и убедитесь, что это соотношение совпадает с вашим результирующим изображением (в вашем случае отношение равно 1.0 из-за 150×150).

В вашем примере, где ширина равна 1050, а высота – 317 пикселей, поэтому вы хотите, чтобы часть исходного изображения составляла 317×317 (соотношение 1.0), вам необходимо:

 subtract 317 from 1050 = 733; // this is the excessive area for both sides divide by 2 =~ 366; // to get the excessive area for one side 

Теперь используйте первую координату x 366, чтобы начать 366 пикселей слева. Используйте вторую координату x 1050 – 366, начиная с 366 пикселей справа.

Таким образом, ваш пример должен быть (просто угадать):

 imagecopyresampled($tmp,$src,0,0,366,0,$newwidth,$newheight, $width - 366, 0); 

Разумеется, вам потребуется некоторая логика, чтобы правильно рассчитать ее для любого другого размера.