Home » Php » math – PHP/GD – Cropping and Resizing Images

math – PHP/GD – Cropping and Resizing Images

Posted by: admin July 12, 2020 Leave a comment

Questions:

I’ve coded a function that crops an image to a given aspect ratio and finally then resizes it and outputs it as 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;
}

?>

The function works as expected but I’m creating a non-required GD image resource, how can I fix it? I’ve tried joining both calls but I must be doing some miscalculations.

<?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');

?>

Any help is greatly appreciated, thanks.

How to&Answers:

You will have to modify your resizing code not to be based on the cropped image to start with. Since you want to do the cropping and resizing in one go you need to calculate it independently.

<?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');

?>