PHP/GD - 裁剪和调整图像大小

标签 php math image-processing image-manipulation gd

我编写了一个函数,可以将图像裁剪为给定的纵横比,最后调整大小并将其输出为 JPG:

<?php

function Image($image, $crop = null, $size = null)
{
    $image = ImageCreateFromString(file_get_contents($image));

    if (is_resource($image) === true)
    {
        $x = 0;
        $y = 0;
        $width = imagesx($image);
        $height = imagesy($image);

        /*
        CROP (Aspect Ratio) Section
        */

        if (is_null($crop) === true)
        {
            $crop = array($width, $height);
        }

        else
        {
            $crop = array_filter(explode(':', $crop));

            if (empty($crop) === true)
            {
                $crop = array($width, $height);
            }

            else
            {
                if ((empty($crop[0]) === true) || (is_numeric($crop[0]) === false))
                {
                    $crop[0] = $crop[1];
                }

                else if ((empty($crop[1]) === true) || (is_numeric($crop[1]) === false))
                {
                    $crop[1] = $crop[0];
                }
            }

            $ratio = array
            (
                0 => $width / $height,
                1 => $crop[0] / $crop[1],
            );

            if ($ratio[0] > $ratio[1])
            {
                $width = $height * $ratio[1];
                $x = (imagesx($image) - $width) / 2;
            }

            else if ($ratio[0] < $ratio[1])
            {
                $height = $width / $ratio[1];
                $y = (imagesy($image) - $height) / 2;
            }

            /*
            How can I skip (join) this operation
            with the one in the Resize Section?
            */

            $result = ImageCreateTrueColor($width, $height);

            if (is_resource($result) === true)
            {
                ImageSaveAlpha($result, true);
                ImageAlphaBlending($result, false);
                ImageFill($result, 0, 0, ImageColorAllocateAlpha($result, 255, 255, 255, 127));

                ImageCopyResampled($result, $image, 0, 0, $x, $y, $width, $height, $width, $height);

                $image = $result;
            }
        }

        /*
        Resize Section
        */

        if (is_null($size) === true)
        {
            $size = array(imagesx($image), imagesy($image));
        }

        else
        {
            $size = array_filter(explode('x', $size));

            if (empty($size) === true)
            {
                $size = array(imagesx($image), imagesy($image));
            }

            else
            {
                if ((empty($size[0]) === true) || (is_numeric($size[0]) === false))
                {
                    $size[0] = round($size[1] * imagesx($image) / imagesy($image));
                }

                else if ((empty($size[1]) === true) || (is_numeric($size[1]) === false))
                {
                    $size[1] = round($size[0] * imagesy($image) / imagesx($image));
                }
            }
        }

        $result = ImageCreateTrueColor($size[0], $size[1]);

        if (is_resource($result) === true)
        {
            ImageSaveAlpha($result, true);
            ImageAlphaBlending($result, true);
            ImageFill($result, 0, 0, ImageColorAllocate($result, 255, 255, 255));
            ImageCopyResampled($result, $image, 0, 0, 0, 0, $size[0], $size[1], imagesx($image), imagesy($image));

            header('Content-Type: image/jpeg');

            ImageInterlace($result, true);
            ImageJPEG($result, null, 90);
        }
    }

    return false;
}

?>

函数按预期工作,但我正在创建一个不需要的 GD 图像资源,我该如何修复它?我试过加入这两个电话,但我一定是计算错误了。

<?php

/*
Usage Examples
*/

Image('http://upload.wikimedia.org/wikipedia/commons/4/47/PNG_transparency_demonstration_1.png', '1:1', '600x');
Image('http://upload.wikimedia.org/wikipedia/commons/4/47/PNG_transparency_demonstration_1.png', '2:1', '600x');
Image('http://upload.wikimedia.org/wikipedia/commons/4/47/PNG_transparency_demonstration_1.png', '2:', '250x300');

?>

非常感谢任何帮助,谢谢。

最佳答案

您必须修改调整大小的代码,使其不以裁剪后的图像为基础。由于您想一次完成裁剪和调整大小,因此需要独立计算。

<?php
function Image($image, $crop = ':', $size = null) {

    $image = ImageCreateFromString(file_get_contents($image));

    if (is_resource($image)) {

        $x = 0;
        $y = 0;
        $width = imagesx($image);
        $height = imagesy($image);

        // CROP (Aspect Ratio) Section
        $crop = array_filter(explode(':', $crop));

        if (empty($crop)) {

            $crop = [$width, $height];

        } else {

            $crop[0] = $crop[0] ?: $crop[1];
            $crop[1] = $crop[1] ?: $crop[0];

        }

        $ratio = [$width / $height, $crop[0] / $crop[1]];

        if ($ratio[0] > $ratio[1]) {

            $width = $height * $ratio[1];
            $x = (imagesx($image) - $width) / 2;

        } else {

            $height = $width / $ratio[1];
            $y = (imagesy($image) - $height) / 2;

        }


        // Resize Section    
        if (is_null($size)) {

            $size = [$width, $height];

        } else {

            $size = array_filter(explode('x', $size));

            if (empty($size)) {

                $size = [imagesx($image), imagesy($image)];

            } else {

                $size[0] = $size[0] ?: round($size[1] * $width / $height);
                $size[1] = $size[1] ?: round($size[0] * $height / $width);

            }
        }

        $result = ImageCreateTrueColor($size[0], $size[1]);

        if (is_resource($result)) {

            ImageSaveAlpha($result, true);
            ImageAlphaBlending($result, true);
            ImageFill($result, 0, 0, ImageColorAllocate($result, 255, 255, 255));
            ImageCopyResampled($result, $image, 0, 0, $x, $y, $size[0], $size[1], $width, $height);

            ImageInterlace($result, true);
            ImageJPEG($result, null, 90);

        }
    }

    return false;
}

header('Content-Type: image/jpeg');
Image('http://upload.wikimedia.org/wikipedia/commons/4/47/PNG_transparency_demonstration_1.png', '1:1', '600x');

?>

关于PHP/GD - 裁剪和调整图像大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/999250/

相关文章:

php - add_menu_page() 不适用于 wordpress 中的插件

php - 在实时服务器上部署 Codeigniter 应用程序

c - 使 a*b < N 的 (a, b) 对数,其中 a、b、N 是大于 0 的整数

java - 在java中解析二次方程

objective-c - 是否有 Objective-C 或 C 数学函数来约束最小值和最大值之间的变量?

java - 将图像分成几部分

php - Symfony2 类的使用

php - Laravel 中未定义的类请求

opencv - 在 calibrateCamera 冗余之后运行 stereoCalibrate 吗?

android - 使用 NDK 在 Android 中进行实时图像处理