Проблема обрезки изображения до идеального квадрата с помощью библиотеки GD - PullRequest
0 голосов
/ 17 июля 2010

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

Любое решение?

Вот как я называю объект:

$resizeObj = new resize($image_file); // *** 1) Initialise / load image
            $resizeObj -> resizeImage(182, 182, 'crop'); // *** 2) Resize image
            $resizeObj -> saveImage($destination_path, 92); // *** 3) Save image

Часть класса, о которой я говорю:

private function getOptimalCrop($newWidth, $newHeight)
    {

        $heightRatio = $this->height / $newHeight;
        $widthRatio  = $this->width /  $newWidth;

        if ($heightRatio < $widthRatio) {
            $optimalRatio = $heightRatio;
        } else {
            $optimalRatio = $widthRatio;
        }

        $optimalHeight = $this->height / $optimalRatio;
        $optimalWidth  = $this->width  / $optimalRatio;

        return array('optimalWidth' => $optimalWidth, 'optimalHeight' => $optimalHeight);
    }

    private function crop($optimalWidth, $optimalHeight, $newWidth, $newHeight)
    {
        // *** Find center - this will be used for the crop
        $cropStartX = ( $optimalWidth / 2) - ( $newWidth /2 );
        $cropStartY = 0; // start crop from top

        $crop = $this->imageResized;
        //imagedestroy($this->imageResized);

        // *** Now crop from center to exact requested size
        $this->imageResized = imagecreatetruecolor($newWidth , $newHeight);
        imagecopyresampled($this->imageResized, $crop , 0, 0, $cropStartX, $cropStartY, $newWidth, $newHeight , $newWidth, $newHeight);
    }

Обновление:

Возможно, изменив это:

$heightRatio = $this->height / $newHeight;
$widthRatio  = $this->width /  $newWidth;

с этим:

$heightRatio = round($this->height / $newHeight);
$widthRatio  = round($this->width /  $newWidth);

1 Ответ

0 голосов
/ 17 июля 2010

Эта строка:

$cropStartX = ( $optimalWidth / 2) - ( $newWidth /2 );

выглядит подозрительно.

Если это целочисленное деление, то для изображений с нечетным числом пикселей в ширину вы получите усечение. Попробуйте:

$cropStartX = ( $optimalWidth / 2.0) - ( $newWidth / 2.0 );

Убедитесь, что во всей вашей арифметике используются действительные числа, предпочтительно с двойной точностью, но с числами в диапазоне, с которым вы работаете, должен быть в порядке для работы с плавающими одинарной точности.

...