<?php
// Информация об исходном изобржение
$src = "/var/tmp/img.png";
$imageInfo = getimagesize($src);
if (!$imageInfo) {
return false;
}
$srcWidth = $imageInfo[0];
$srcHeight = $imageInfo[1];
switch ($imageInfo[2]) {
case 1:
$src = imagecreatefromgif($src);
$ext = ".gif";
break;
case 2:
$src = imagecreatefromjpeg($src);
$ext = ".jpg";
break;
case 3:
$src = imagecreatefrompng($src);
$ext = ".png";
break;
default:
return false;
break;
}
$maxHeight = 80;
$maxWidth = 120;
$kWidth = $srcWidth/$maxWidth;
$kHeight = $srcHeight/$maxHeight;
// посольку коэфициент расчитан путем деления большей стороны на меньшую, то выбираем меньший (k>1),
// если бы делили меньшую на большую, то выбирали бы макс. значение (k < 1)
$k = min($kHeight, $kWidth);
// тут мы получим ширину и высоту большего изображения, чем нужно *что бы было что отрезать от других сторон
$tmpWidth = round($srcWidth/$k);
$tmpHeight = round($srcHeight/$k);
// вычисляем размеры конечного изображения
$dstWidth = $tmpWidth - ($tmpWidth-$maxWidth);
$dstHeight = $tmpHeight - ($tmpHeight-$maxHeight);
// вичисляем сдвиг (т.е., это ровно половина разницы между соот. сторонами временной миниатюрой и нужной нам миниатурой)
$wOffset = $tmpWidth > $maxWidth ? ($tmpWidth-$maxWidth)/2 : 0;
$hOffset = $tmpHeight > $maxHeight ? ($tmpHeight-$maxHeight)/2 : 0;
// Напримепр, нам нужно получить изображение которое должно быть строго 120x80
// наше исходное изобржение 1000x1000,
// таким образом в $tmp будет лежать фото размером 120x120
$tmp = imagecreatetruecolor($tmpWidth, $tmpHeight);
// а тут будет фото 120x80
$dst = imagecreatetruecolor($dstWidth, $dstHeight); // сюда ложим
// ресайзим (120x120)
imagecopyresampled($tmp, $src, 0, 0, 0, 0, $tmpWidth, $tmpHeight, $srcWidth, $srcHeight); // ресайзим
// копируем область с параметрами
// с параметрами do, to, dx, dy, tx, ty, dw, dh, где
// do = $dst (GD Object)
// to = $tmp (GD Object)
// dx,dy - координаты левого верхнего угла области на конечном полотне, куда будет всталена скопированная область, в нашем случае всегда 0,0
// tx, ty - кординаты левого верхнего угла обалсти на временном полотне, откуда будет скорпированна область, в нашем случае это 0,20
// dw, dh - ширина и высота прямоугольника, в нашем случае 120, 80
imagecopy ($dst, $tmp, 0, 0, $wOffset, $hOffset, $dstWidth, $dstHeight);
switch ($ext) {
case ".jpg": $result = imagejpeg($dst,"/var/tmp/humb_120x80".$ext, 100);break;
case ".png": $result = imagepng($dst,"/var/tmp/humb_120x80".$ext, 5);break;
case ".gif": $result = imagegif($dst, "/var/tmp/humb_120x80".$ext, 100);break;
}
var_dump($result);
Читай внимательно отношение всегда больше 0. А некое xPos, которое высчитывает товарищ Духовность, может быть отрицательным и это ломает вызов imageCopyResampled, который не может взять отрицательную координату.Код в котором отношение сторон двух прямоугольников может быть отрицательно - не код, двоешники
Давай общаться без этих ораторских приемчиков. Ты наверняка понял что я имею ввиду. твое решение - классическое, математически правильное, общее. Мое - с рассмотрением двух частных случаев, которые покрывают почти все множество вариантов(кроме исключений типа отрицательной необходимой ширины). Зато с одним копированием картинки.. и как мне кажется более простое для обьяснения. Я бы его назвал "программистским".Не знаю, чего сложного в функциях min, max.
function lib_imageTumbnail($srcFileName, $destFileName,
$thumbWidth/*120 for example*/, $thumbHeight/*80 for example*/, $quality = 70)
{
// получаем картинковый обьект
$srcImage = getImageObject($srcFileName);
if(!$srcImage) return false;
$srcWidth = imagesx($srcImage);
$srcHeight = imagesy($srcImage);
$srcRatio = $srcWidth / $srcHeight; // коеф фотки
$destRatio = $thumbWidth / $thumbHeight; // коеф стандартный
if($srcRatio > $destRatio)
{
// фотка больше, чем надо, в ширину. Вычисляем отступ по горизонтали.
$cropWidth = round($srcHeight * $destRatio);
$cropHeight = $srcHeight;
$cropLeft = round( ($srcWidth - $cropWidth) / 2);
$cropTop = 0;
}
else
{
// фотка больше, чем надо, в высоту. Вычисляем отступ по вертикали.
$croppedHeight = round($srcWidth / $destRatio);
$croppedWidth = $srcWidth;
$cropTop = round( ($srcHeight - $croppedHeight) / 2);
$cropLeft = 0;
}
$destImage = imagecreatetruecolor($thumbWidth, $thumbHeight);
imagecopyresampled($destImage, $srcImage, 0, 0, $cropLeft, $cropTop,
$thumbWidth, $thumbHeight, $croppedWidth, $croppedHeight);
imagejpeg($destImage, $destFileName, $quality);
imagedestroy($srcImage);
imagedestroy($destImage);
return true;
}
$croppedHeight = round($srcWidth / $destRatio); // это что?
$croppedWidth = $srcWidth;
Чего ты все переиначиваешь? Есть - отношение сторон исходной фигуры и отношение сторон требуемое.Вопрос - Как отношение собственных сторон одной фигуры может влиять на коэффициент масштаба изображения?
lib_imageTumbnail("img.jpg", "humb.jpg", 120, 80); // работет
lib_imageTumbnail("img.jpg", "humb.jpg", 120, 100); // черный прямоугольник
lib_imageTumbnail("img.jpg", "humb.jpg", 120, 120); // черный квадрат
lib_imageTumbnail("img.jpg", "humb.jpg", 110, 120); // черный прямоугольник
lib_imageTumbnail("img.jpg", "humb.jpg", 80, 120); // черный прямоугольник
<?php
$src = "avatar.jpg";
$imageInfo = getimagesize($src);
$srcWidth = $imageInfo[0];
$srcHeight = $imageInfo[1];
$src = imagecreatefromjpeg($src);
$maxWidth = 100;
$maxHeight = 100;
$k = min($srcHeight/$maxHeight, $srcWidth/$maxWidth);
$k = $k > 1 ? $k : 1;
$xDiff = $srcWidth/$k - $maxWidth > 0 ? $srcWidth/$k - $maxWidth : 0;
$yDiff = $srcHeight/$k - $maxHeight > 0 ? $srcHeight/$k - $maxHeight: 0;
$dst = imagecreatetruecolor($srcWidth/$k-$xDiff, $srcHeight/$k-$yDiff);
imagecopyresampled($dst, $src, 0, 0, $xDiff/2*$k, $yDiff/2*$k, $srcWidth/$k-$xDiff, $srcHeight/$k-$yDiff, $srcWidth-$xDiff*$k, $srcHeight-$yDiff*$k);
header("Content-type: image/jpeg");
imagejpeg($dst, null, 100);
?>
$k = max($srcHeight/$maxHeight, $srcWidth/$maxWidth);
Верно. Я же говорил - у тебя более правильный и математически выверенный вариант. Но расчеты сложноваты. Ну да ладно Пора нам завязывать дискуссию.Ты вычисляешь, горизонтальная у тебя фото или нет, с какой стороны отрезать, впишется ли оно у тебя в заданную область или нет, хотя по идее - не должно волновать, какой по соотношению сторон источник.
Эт не бага. Это фича Цель была - строить изображение заданного мастаба из исходного. Если оно меньше - то увеличиваем... Нелогично? мэйбиВо! Нашел багу, если источник будет меньше миниатюры, то твой код отвалится, он будет увеличивать, с моим все будет ок
<?php
$src = "avatar.jpg";
$crop = true;
$zoom = false;
$src = imagecreatefromjpeg($src);
$srcWidth = imagesx($src);
$srcHeight = imagesy($src);
$maxWidth = 120;
$maxHeight = 80;
$k = $crop ? min($srcHeight/$maxHeight, $srcWidth/$maxWidth) : max($srcHeight/$maxHeight, $srcWidth/$maxWidth);
$k = !$zoom && $k < 1 ? 1 : $k;
$xDiff = $srcWidth/$k - $maxWidth > 0 ? $srcWidth/$k - $maxWidth : 0;
$yDiff = $srcHeight/$k - $maxHeight > 0 ? $srcHeight/$k - $maxHeight: 0;
$dst = imagecreatetruecolor($srcWidth/$k-$xDiff, $srcHeight/$k-$yDiff);
imagecopyresampled($dst, $src, 0, 0, $xDiff/2*$k, $yDiff/2*$k, $srcWidth/$k-$xDiff, $srcHeight/$k-$yDiff, $srcWidth-$xDiff*$k, $srcHeight-$yDiff*$k);
header("Content-type: image/jpeg"); imagejpeg($dst, null, 100);
?>
Угу. +1. небесполезный тред оказался, имхо.Ладно, дальнейший спор не имеет смысла