Изменение размера и обрезка изображения с помощью GD с сохранением соотношения сторон

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

Это мой код на данный момент:

if ($fileExtension == "jpg" || 
        $fileExtension == "jpeg" || 
        $fileExtension == "png" || 
        $fileExtension == "gif"){

        // GD variables:
        list($width, $height, $type) = GetImageSize($uploadedFile['tmp_name']);

        // Image sizes:
        $bigImage = array(800, 453);
        $mediumImage = array(410, 231);
        $listImage = array(120, 68);
        $thumbnail = array(90, 51);

        $sourceAspect = $width / $height;
        $bigAspect = $bigImage[0] / $bigImage[1];
        $mediumAspect = $mediumImage[0] / $mediumImage[1];
        $listAspect = $listImage[0] / $listImage[1];
        $thumbnailAspect = $thumbnail[0] / $thumbnail[1];

        // Image is PNG:
        if ($type == IMAGETYPE_PNG){
            $image = imagecreatefrompng($uploadedFile['tmp_name']);
            $valid = true;
        }

        // Image is JPEG:
        else if ($type == IMAGETYPE_JPEG){
            $image = imagecreatefromjpeg($uploadedFile['tmp_name']);
            $valid = true;
        }

        // Image is GIF:
        else if ($type == IMAGETYPE_GIF){
            $image = imagecreatefromgif($uploadedFile['tmp_name']);
            $valid = true;
        }

        // Format not allowed:
        else {
            $valid = false;
        }

        // Start creating images:
        if ($valid){

            // Get size:
            $imageSize = getimagesize($uploadedFile['tmp_name']);

            // Generate canvas:
            $bCanvas = imagecreatetruecolor($bigImage[0], $bigImage[1]);
            $mCanvas = imagecreatetruecolor($mediumImage[0], $mediumImage[1]);
            $lCanvas = imagecreatetruecolor($listImage[0], $listImage[1]);
            $tCanvas = imagecreatetruecolor($thumbnail[0], $thumbnail[1]);

            // Copy content:
            imagecopyresampled($bCanvas, $image, 0, 0, 0, 0, ($bigImage[0] * $sourceAspect), ($bigImage[1] / $sourceAspect), $imageSize[0], $imageSize[1]);
            imagecopyresampled($mCanvas, $image, 0, 0, 0, 0, $mediumImage[0], $mediumImage[1], $imageSize[0], $imageSize[1]);
            imagecopyresampled($lCanvas, $image, 0, 0, 0, 0, $listImage[0], $listImage[1], $imageSize[0], $imageSize[1]);
            imagecopyresampled($tCanvas, $image, 0, 0, 0, 0, $thumbnail[0], $thumbnail[1], $imageSize[0], $imageSize[1]);

            // Save images:
            $saveB = imagejpeg($bCanvas, $targetFile.'_big.jpg', 90);
            $saveM = imagejpeg($mCanvas, $targetFile.'_medium.jpg', 90);
            $saveT = imagejpeg($lCanvas, $targetFile.'_list.jpg', 90);
            $saveT = imagejpeg($tCanvas, $targetFile.'_thumb.jpg', 90);

            // Destroy images:
            imagedestroy($image);
            imagedestroy($bCanvas);
            imagedestroy($mCanvas);
            imagedestroy($lCanvas);
            imagedestroy($tCanvas);

            // Watermark images:
            $mark = imagecreatefrompng("logo.png");
            list($mwidth, $mheight) = getimagesize("logo.png");
            $img = imagecreatefromjpeg($targetFile.'_big.jpg');

            list($bwidth, $bheight) = getimagesize($targetFile.'_big.jpg');
            imagecopy($img, $mark, $bwidth-$mwidth-25, $bheight-$mheight-25, 0, 0, $mwidth, $mheight);
            imagejpeg($img, $targetFile.'_big.jpg', 100);
            imagedestroy($img);

        } else {
            echo "0";
        }

    } else {
        move_uploaded_file($tempFile,$targetFile.'.'.$fileExtension);
    }

Я был бы очень рад, если бы кто-нибудь помог мне решить эту проблему. Я пробовал несколько методов, но ни один из них не работал должным образом. Как вы можете видеть вверху, я уже определил размеры холста, которые хочу использовать в переменных «bigImage», «mediumImage», «listImage» и «thumbnail».

Заранее спасибо! // Джонатан


person Jonathan    schedule 06.09.2011    source источник
comment
Насколько я помню, вы не можете сделать это с GD, хотя Imagick предоставит такие возможности.   -  person markus    schedule 06.09.2011


Ответы (1)


Есть несколько способов изменить размер изображения. Я расскажу вам их по буквам:

  • Растянуть по размеру - изображение изменяется до желаемого размера без учета соотношения сторон.
  • Масштабировать по размеру - изображение изменяется так, чтобы одно измерение (ширина или высота) имело желаемый размер, а другое было таким же или короче при сохранении соотношения сторон (может потребоваться один дополнительный шаг, чтобы заполнить более короткую сторону сплошным цветом)
  • Обрезать по размеру - изображение изменяется таким образом, чтобы одно измерение (ширина или высота) имело желаемый размер, а другое - такое же или длиннее, при этом сохраняется соотношение сторон (требуется один дополнительный шаг для обрезки внешней области)

PS: обе статьи написаны мной.

person Salman A    schedule 06.09.2011
comment
Спасибо, я попытался использовать вашу статью, но у меня получилось полностью черное изображение. Не знаю почему, но я несколько раз перебирал код и не могу найти проблему. Вот мой код, использующий ваши функции: pastebin.com/XgDvUEWe - person Jonathan; 06.09.2011
comment
@Jonathan, я включил полный отчет об ошибках, чтобы найти проблему; измененная версия пасты доступна по адресу pastebin.com/J41aPe9g - person Salman A; 06.09.2011
comment
@Salman Спасибо, хорошие статьи, и они действительно помогли мне сэкономить время. - person devloper; 17.02.2014