[Phpwm] PHP Image Manipulation

Dave Holmes dave at neteffekt.co.uk
Fri Nov 21 16:07:17 UTC 2008


Hi Pete,

We have done a bit with images in our systems allowing people to upload
images into the e-commerce application and then scale them to fit,
this code might be helpful as a wrapper around GD

Dave

  class image_manipulation extends core_item
    {   
        # Path and name of image file to transform
        public $sourceFile;
        # Path and name of transformed image file
        public $targetFile; 
        # Available only for the {@link resize} method
        # Width, in pixels, to resize the image to
        # the property will not be taken into account if is set to -1
        # default is -1
        public $resizeToWidth;
        # Available only for the {@link resize} method
        # Height, in pixels, to resize the image to
        # the property will not be taken into account if is set to -1
        # default is -1
        public $resizeToHeight;
        # Available only for the {@link resize} method
        # while resizing, image will keep it's aspect ratio if this
property is set to TRUE, and only one of the
        # {@link resizeToWidth} or {@link resizeToHeight} properties is
set. if set to TRUE, and both
        # {@link resizeToWidth} or {@link resizeToHeight} properties are
set, the image will be resized to maximum width/height
        # so that neither one of them will exceed given width/height
while keeping the aspect ratio
        # default is TRUE
        public $maintainAspectRatio;
        # Available only for the {@link resize} method
        # image is resized only if image width/height is smaller than
the values of
        # {@link resizeToWidth}/{@link resizeToHeight} properties
        # default is TRUE
        public $resizeIfSmaller;
        # Available only for the {@link resize} method
        # image is resized only if image width/height is greater than
the values of
        # {@link resizeToWidth}/{@link resizeToHeight} properties
        # default is TRUE
        public $resizeIfGreater;
        # Available only for the {@link resize} method and only if the
{@link targetFile}'s extension is jpg/jpeg
        # output quality of image (better quality means bigger file size).
        # range is 0 - 100
        # default is 75
        public $jpegOutputQuality;
        # in case of an error read this property's value to find out
what went wrong
        # possible error values are:
        # *
        # *      - 1:  source file could not be found
        # *      - 2:  source file can not be read
        # *      - 3:  could not write target file
        # *      - 4:  unsupported source file
        # *      - 5:  unsupported target file
        # *      - 6:  available version of GD does not support target
file extension
        # *
        # *  default is 0
        public $error;

        # Class constructor
        function image_handler()
        {
            # Sets default values of the class' properties
            # We need to do it this way for the variables to have
default values PHP 4
            # public properties
            $this->error = 0;
            $this->jpegOutputQuality = 75;
            $this->resizeIfGreater = true;
            $this->resizeIfSmaller = true;
            $this->maintainAspectRatio = true;
            $this->resizeToHeight = -1;
            $this->resizeToWidth = -1;
            $this->targetFile = "";
            $this->sourceFile = "";
        }
       
        # This function will decode the error code to provide a sensible
message for the integer value
        # this will allow the classes descended from this image library
to extract the information they require
        function get_image_error_message($error_code)
        {
            # Return the appropriate error message
            if ($error_code == 1) return 'source file could not be found';
            if ($error_code == 2) return 'source file could not be read';
            if ($error_code == 3) return 'could not write target file';
            if ($error_code == 4) return 'unsupported source file';
            if ($error_code == 5) return 'unsupported target file';
            if ($error_code == 6) return 'available version of GD does
not support target file extension';
        }
       
        # returns an image identifier representing the image obtained
from sourceFile and the image's width and height
        function create_image_from_source_file()
        {
            # performs some error checking first
            # if source file does not exists
            if (!file_exists($this->sourceFile)) {
                print_r("a");
                # save the error level and stop the execution of the script
                $this->error = 1;
                return false;
            # if source file is not readable
            } elseif (!is_readable($this->sourceFile)) {
                # save the error level and stop the execution of the script
                $this->error = 2;
                return false;
            # if target file is same as source file and source file is
not writable
            } elseif ($this->targetFile == $this->sourceFile &&
!is_writable($this->sourceFile)) {
                # save the error level and stop the execution of the script
                $this->error = 3;
                return false;
            # get source file width, height and type
            # and if founds a not-supported file type
            } elseif (!list($sourceImageWidth, $sourceImageHeight,
$sourceImageType) = @getimagesize($this->sourceFile)) {
                # save the error level and stop the execution of the script
                $this->error = 4;
                return false;
            # if no errors so far
            } else {
   
                # creates an image from file using extension dependant
function
                # checks for file extension
                switch ($sourceImageType) {
                    # if gif
                    case 1:
                        # the following part gets the transparency color
for a gif file
                        # this code is from the PHP manual and is written by
                        # fred at webblake dot net and webmaster at
webnetwizard dotco dotuk, thanks!
                        $fp = fopen($this->sourceFile, "rb");
                        $result = fread($fp, 13);
                        $colorFlag = ord(substr($result,10,1)) >> 7;
                        $background = ord(substr($result,11));
                        if ($colorFlag) {
                            $tableSizeNeeded = ($background + 1) * 3;
                            $result = fread($fp, $tableSizeNeeded);
                            $this->transparentColorRed =
ord(substr($result, $background * 3, 1));
                            $this->transparentColorGreen =
ord(substr($result, $background * 3 + 1, 1));
                            $this->transparentColorBlue =
ord(substr($result, $background * 3 + 2, 1));
                        }
                        fclose($fp);
                        # -- here ends the code related to transparency
handling
                        # creates an image from file
                        $sourceImageIdentifier =
@imagecreatefromgif($this->sourceFile);
                        break;
                    # if jpg
                    case 2:
                        # creates an image from file
                        $sourceImageIdentifier =
@imagecreatefromjpeg($this->sourceFile);
                        break;
                    # if png
                    case 3:
                        # creates an image from file
                        $sourceImageIdentifier =
@imagecreatefrompng($this->sourceFile);
                        break;
                    default:
                        # if file has an unsupported extension
                        # note that we call this if the file is not gif,
jpg or png even though the getimagesize function
                        # handles more image types
                        $this->error = 4;
                        return false;
                }
            }
            # returns an image identifier representing the image
obtained from sourceFile and the image's width and height
            return array($sourceImageIdentifier, $sourceImageWidth,
$sourceImageHeight);
        }
   
        #Creates a target image identifier
        function create_target_image_identifier($width, $height)
        {
            # creates a blank image
            $targetImageIdentifier = imagecreatetruecolor($width, $height);
            # if we have transparency in the image
            if (isset($this->transparentColorRed) &&
isset($this->transparentColorGreen) && isset($this->transparentColorBlue)) {
                $transparent =
imagecolorallocate($targetImageIdentifier, $this->transparentColorRed,
$this->transparentColorGreen, $this->transparentColorBlue);
                imagefilledrectangle($targetImageIdentifier, 0, 0,
$width, $height, $transparent);
                imagecolortransparent($targetImageIdentifier, $transparent);
            }
            # return target image identifier
            return $targetImageIdentifier;
        }
   
        # creates a new image from a given image identifier
        function output_target_image($targetImageIdentifier)
        {
            # get target file extension
            $targetFileExtension = strtolower(substr($this->targetFile,
strrpos($this->targetFile, ".") + 1));
            # image saving process goes according to required extension
            switch ($targetFileExtension) {
                # if gif
                case "gif":
                    # if gd support for this file type is not available
                    if (!function_exists("imagegif")) {
                        # save the error level and stop the execution of
the script
                        $this->error = 6;
                        return false;
                    # if, for some reason, file could not be created
                    } elseif (@!imagegif($targetImageIdentifier,
$this->targetFile)) {
                        # save the error level and stop the execution of
the script
                        $this->error = 3;
                        return false;
                    }
                    break;
                # if jpg
                case "jpg":
                case "jpeg":
                    # if gd support for this file type is not available
                    if (!function_exists("imagejpeg")) {
                        # save the error level and stop the execution of
the script
                        $this->error = 6;
                        return false;
                    # if, for some reason, file could not be created
                    } elseif (@!imagejpeg($targetImageIdentifier,
$this->targetFile, $this->jpegOutputQuality)) {
                        # save the error level and stop the execution of
the script
                        $this->error = 3;
                        return false;
                    }
                    break;
                case "png":
                    # if gd support for this file type is not available
                    if (!function_exists("imagepng")) {
                        # save the error level and stop the execution of
the script
                        $this->error = 6;
                        return false;
                    # if, for some reason, file could not be created
                    } elseif (@!imagepng($targetImageIdentifier,
$this->targetFile)) {
                        # save the error level and stop the execution of
the script
                        $this->error = 3;
                        return false;
                    }
                # if not a supported file extension
                default:
                    # save the error level and stop the execution of the
script
                    $this->error = 5;
                    return false;
            }
            # and return true
            return true;
        }
   
        # Resizes the image given as {@link sourceFile} and outputs the
resulted image as {@link targetFile}
        # while following user specified properties,  TRUE on success,
FALSE on error.
        # If FALSE is returned, check the {@link error} property to see
what went wrong
        function resize()
        {
            # tries to create an image from sourceFile and continues if
operation was successful
            if (list($sourceImageIdentifier, $sourceImageWidth,
$sourceImageHeight) = $this->create_image_from_source_file()) {
                # if aspect ratio needs to be maintained
                if ($this->maintainAspectRatio) {
                    # calculates image's aspect ratio
                    $aspectRatio =
                        $sourceImageWidth <= $sourceImageHeight ?
                            $sourceImageHeight / $sourceImageWidth :
                            $sourceImageWidth / $sourceImageHeight;
                    $targetImageWidth = $sourceImageWidth;
                    $targetImageHeight = $sourceImageHeight;
                    # if width of image is greater than resizeToWidth
property and resizeIfGreater property is TRUE
                    # or width of image is smaller than resizeToWidth
property and resizeIfSmaller property is TRUE
                    if (
                        ($this->resizeToWidth >= 0 && $targetImageWidth
> $this->resizeToWidth && $this->resizeIfGreater) ||
                        ($this->resizeToWidth >= 0 && $targetImageWidth
< $this->resizeToWidth && $this->resizeIfSmaller)
                    ) {
                        # set the width of target image
                        $targetImageWidth = $this->resizeToWidth;
                        # set the height of target image so that the
image will keep its aspect ratio
                        $targetImageHeight =
                            $sourceImageWidth <= $sourceImageHeight ?
                                $targetImageWidth * $aspectRatio :
                                $targetImageWidth / $aspectRatio;
                        # saves the got width in case the next section
wants to change it
                        $lockedTargetImageWidth = $targetImageWidth;
                    }
                    # if height of image is greater than resizeToHeight
property and resizeIfGreater property is TRUE
                    # or height of image is smaller than resizeToHeight
property and resizeIfSmaller property is TRUE
                    if (
                        ($this->resizeToHeight >= 0 &&
$targetImageHeight > $this->resizeToHeight && $this->resizeIfGreater) ||
                        ($this->resizeToHeight >= 0 &&
$targetImageHeight < $this->resizeToHeight && $this->resizeIfSmaller)
                    ) {
                        # set the width of target image
                        $targetImageHeight = $this->resizeToHeight;
                        # set the width of target image so that the
image will keep its aspect ratio
                        $targetImageWidth =
                            $sourceImageWidth <= $sourceImageHeight ?
                                $targetImageHeight / $aspectRatio :
                                $targetImageHeight * $aspectRatio;
                        # if maximum width was already set but has
changed now
                        if (
                            isset($lockedTargetImageWidth) &&
                            $targetImageWidth > $lockedTargetImageWidth
                        ) {
                            # adjust the height so that the width
remains as set before
                            while ($targetImageWidth >
$lockedTargetImageWidth) {
                                $targetImageHeight--;
                                $targetImageWidth =
                                    $sourceImageWidth <=
$sourceImageHeight ?
                                        $targetImageHeight / $aspectRatio :
                                        $targetImageHeight * $aspectRatio;
                            }
                        }
                    }
                # if aspect ratio does not need to be maintained
                } else {
                    $targetImageWidth = ($this->resizeToWidth >= 0 ?
$this->resizeToWidth : $sourceImageWidth);
                    $targetImageHeight = ($this->resizeToHeight >= 0 ?
$this->resizeToHeight : $sourceImageHeight);
                }
                # prepares the target image
                $targetImageIdentifier =
$this->create_target_image_identifier($targetImageWidth,
$targetImageHeight);
                # resizes image
                imagecopyresampled($targetImageIdentifier,
$sourceImageIdentifier, 0, 0, 0, 0, $targetImageWidth,
$targetImageHeight, $sourceImageWidth, $sourceImageHeight);
                # writes image
                return $this->output_target_image($targetImageIdentifier);
            # if new image resource could not be created
            } else {
                # return false
                # note that we do not set the error level as it has been
already set
                # by the create_image_from_source_file() method earlier
                return false;
            }
        }
   
        # Flips horizontally the image given as {@link sourceFile} and
outputs the resulted image as {@link targetFile}
        # returns TRUE on success, FALSE on error.  If FALSE is
returned, check the {@link error} property to see what went wrong
        function flip_horizontal()
        {
            # tries to create an image from sourceFile and continues if
operation was successful
            if (list($sourceImageIdentifier, $sourceImageWidth,
$sourceImageHeight) = $this->create_image_from_source_file()) {
                # prepares the target image
                $targetImageIdentifier =
$this->create_target_image_identifier($sourceImageWidth,
$sourceImageHeight);
                # flips image horizontally
                for ($x = 0; $x < $sourceImageWidth; $x++) {
                   imagecopy($targetImageIdentifier,
$sourceImageIdentifier, $x, 0, $sourceImageWidth - $x - 1, 0, 1,
$sourceImageHeight);
                }
                # writes image
                return $this->output_target_image($targetImageIdentifier);
            # if new image resource could not be created
            } else {
                # return false
                # note that we do not set the error level as it has been
already set
                # by the create_image_from_source_file() method earlier
                return false;
            }
        }
   
        # Flips vertically the image given as {@link sourceFile} and
outputs the resulted image as {@link targetFile}
        # returns TRUE on success, FALSE on error.  If FALSE is
returned, check the {@link error} property to see what went wrong
        function flip_vertical()
        {
            # tries to create an image from sourceFile and continues if
operation was successful
            if (list($sourceImageIdentifier, $sourceImageWidth,
$sourceImageHeight) = $this->create_image_from_source_file()) {
                # prepares the target image
                $targetImageIdentifier =
$this->create_target_image_identifier($sourceImageWidth,
$sourceImageHeight);
                # flips image vertically
                for ($y = 0; $y < $sourceImageHeight; $y++) {
                    imagecopy($targetImageIdentifier,
$sourceImageIdentifier, 0, $y, 0, $sourceImageHeight - $y - 1,
$sourceImageWidth, 1);
                }
                # writes image
                return $this->output_target_image($targetImageIdentifier);
            # if new image resource could not be created
            } else {
                # return false
                # note that we do not set the error level as it has been
already set
                # by the create_image_from_source_file() method earlier
                return false;
            }
        }
   
        # Rotates the image given as {@link sourceFile} and outputs the
resulted image as {@link targetFile}
        # this method implements PHP's imagerotate method which is
buggy. an improved version of this method should be available soon
        # returns TRUE on success, FALSE on error.  If FALSE is
returned, check the {@link error} property to see what went wrong
        function rotate($angle, $bgColor)
        {
            # tries to create an image from sourceFile and continues if
operation was successful
            if (list($sourceImageIdentifier, $sourceImageWidth,
$sourceImageHeight) = $this->create_image_from_source_file()) {
                # rotates image
                $targetImageIdentifier =
imagerotate($sourceImageIdentifier, $angle, $bgColor);
                # writes image
                return $this->output_target_image($targetImageIdentifier);
            # if new image resource could not be created
            } else {
                # return false
                # note that we do not set the error level as it has been
already set
                # by the create_image_from_source_file() method earlier
                return false;
            }
        }
    }
   

pete graham wrote:
> Hi Everybody,
>
> I was looking to use a class to do some basic image manipulation
> (resizing, converting types, cropping, etc). I haven't done anything
> like this is a while so wondered what recommendations people have. If
> it's really simple image manipulation am I best off just using the
> built in GD functions?
>
> Thank you, Pete
>
> _______________________________________________
> Phpwm mailing list
> Phpwm at mailman.lug.org.uk
> https://mailman.lug.org.uk/mailman/listinfo/phpwm
>



More information about the Phpwm mailing list