使用 GD 库将图像裁剪为完美正方形时出现问题

发布于 2024-09-10 11:08:08 字数 1977 浏览 5 评论 0原文

我使用一个类,它根据某些选项自动将图像裁剪为正方形。问题是,当图像具有一定的宽度和高度时,图像会被裁剪,但会在图像右侧添加一列 1px 的黑色像素。我认为问题出在用于生成新图像尺寸的数学中...也许当高度和宽度的除法给出十进制数时,正方形不完美并且添加了黑色像素...

任何解决方案?

这就是我调用该对象的方式:

$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);

I use a class that automatically crops an image as a square based on some options. The problem is that when the image is of a certain width and height, the image is cropped but a 1px column of black pixels is added to the right of the image. I think that the problem is in the mathematics used to generate the new image size... Maybe when the division of the height and the width gives a decimal number then the square is not perfect and the black pixels are added...

Any solution?

This is how I call the object:

$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

The part of the class I'm talking about:

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);
    }

Update:

Maybe changing this:

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

with this:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

年少掌心 2024-09-17 11:08:08

这行:

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

看起来很可疑。

如果这是整数除法,那么对于奇数像素宽的图像,您将得到截断。尝试:

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

确保所有算术都使用实数,最好是双精度实数,但是对于您正在处理的范围内的数字,应该可以在单精度浮点数中工作。

This line:

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

looks suspicious.

If this is integer division then for images that are an odd number of pixels wide you'll get truncation. Try:

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

Make sure that all your arithmetic is using real numbers, preferably double precision ones, but with numbers in the range you are dealing with it should be OK to work in single precision floats.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文