Я хочу изменить размеры изображений на фиксированную ширину и высоту (то есть 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);
Разумеется, вам потребуется некоторая логика, чтобы правильно рассчитать ее для любого другого размера.