0

I have found many questions about this on SO but none seem to solve my issue.

I need to resize images and save them to specific directories. My class below works exactly as I need it with the exception of transparent images. The transparent images turn black where they should be transparent.

Modified class of SimpleImage

<?php
/**
 * Class ImageResize
 */
class ImageResize {
    /**
     * Image
     * @var resource
     */
    var $image;

    /**
     * Image type
     * @var int
     */
    var $image_type;

    /**
     * Loads the image file
     * @param $filename
     */
    function load($filename) {
        $image_info = getimagesize($filename);
        $this->image_type = $image_info[2];
        unset($image_info);
        if ($this->image_type == IMAGETYPE_JPEG) {
            $this->image = imagecreatefromjpeg($filename);
        } elseif ($this->image_type == IMAGETYPE_GIF) {
            $this->image = imagecreatefromgif($filename);
        } elseif ($this->image_type == IMAGETYPE_PNG) {
            $this->image = imagecreatefrompng($filename);
        }
    }

    /**
     * Saves the image file
     * @param $filename
     * @param int $image_type
     * @param int $compression
     * @param null $permissions
     */
    function save($filename, $image_type = IMAGETYPE_JPEG, $compression = 75, $permissions = NULL) {
        if ($image_type == IMAGETYPE_JPEG) {
            imagejpeg($this->image, $filename, $compression);
        } elseif ($image_type == IMAGETYPE_GIF) {
            imagegif($this->image, $filename);
        } elseif ($image_type == IMAGETYPE_PNG) {
            imagepng($this->image, $filename);
        }
        if ($permissions != NULL) {
            chmod($filename, $permissions);
        }
    }

    /**
     * Outputs the image file
     * @param int $image_type
     */
    function output($image_type = IMAGETYPE_JPEG) {
        if ($image_type == IMAGETYPE_JPEG) {
            imagejpeg($this->image);
        } elseif ($image_type == IMAGETYPE_GIF) {
            imagegif($this->image);
        } elseif ($image_type == IMAGETYPE_PNG) {
            imagepng($this->image);
        }
    }

    /**
     * Gets the image width
     * @return int
     */
    function getWidth() {
        return imagesx($this->image);
    }

    /**
     * Gets the image height
     * @return int
     */
    function getHeight() {
        return imagesy($this->image);
    }

    /**
     * Resize the image to a specified height
     * @param $height
     */
    function resizeToHeight($height) {
        $ratio = $height / $this->getHeight();
        $width = $this->getWidth() * $ratio;
        $this->resize($width, $height);
        unset($ratio, $width);
    }

    /**
     * Resize the image to a specified width
     * @param $width
     */
    function resizeToWidth($width) {
        $actualWidth = $this->getWidth();
        if ($width < $actualWidth) {
            $ratio  = $width / $actualWidth;
            $height = $this->getheight() * $ratio;
            $this->resize($width, $height);
        }
        unset($actualWidth, $ratio, $height);
    }

    /**
     * Scales the image
     * @param $scale
     */
    function scale($scale) {
        $width  = $this->getWidth() * $scale / 100;
        $height = $this->getheight() * $scale / 100;
        $this->resize($width, $height);
        unset($width, $height);
    }

    /**
     * Resize the image
     * @param $width
     * @param $height
     */
    function resize($width, $height) {
        $new_image = imagecreatetruecolor($width, $height);
        imagecopyresampled($new_image, $this->image, 0, 0, 0, 0, $width, $height, $this->getWidth(), $this->getHeight());
        $this->image = $new_image;
        unset($new_image);
    }

}

I have tried these fixes as I have found throughout SO and the all mighty Google:

Note: These fixes are added to the resize method.

First Fix:

function resize($width, $height) {
    $new_image = imagecreatetruecolor($width, $height);

    // Attempt fix transparency
    if ($this->image_type == IMAGETYPE_PNG || $this->image_type == IMAGETYPE_GIF) {
        // Even tried with 255, 255, 255 for white and still no good
        imagecolortransparent($new_image, imagecolorallocatealpha($new_image, 0, 0, 0, 127));
        imagealphablending($new_image, false);
        imagesavealpha($new_image, true);
    }

    imagecopyresampled($new_image, $this->image, 0, 0, 0, 0, $width, $height, $this->getWidth(), $this->getHeight());
    $this->image = $new_image;
    unset($new_image);
}

The first fix does not change the black to white and it makes the image quality very low. So this doesn't seem to work properly.

Second Fix:

function resize($width, $height) {
    $new_image = imagecreatetruecolor($width, $height);

    if ($this->image_type == IMAGETYPE_PNG || $this->image_type == IMAGETYPE_GIF) {
            $colourBlack = imagecolorallocate($new_image, 0, 0, 0);
            imagecolortransparent($new_image, $colourBlack);
    }

    imagecopyresampled($new_image, $this->image, 0, 0, 0, 0, $width, $height, $this->getWidth(), $this->getHeight());
    $this->image = $new_image;
    unset($new_image);
}

The second fix didn't seem to fix the black background either and the quality wasn't too bad but it could be better.

Third Fix:

function resize($width, $height) {
    $new_image = imagecreatetruecolor($width, $height);

    if ($this->image_type == IMAGETYPE_PNG || $this->image_type == IMAGETYPE_GIF) {
        imagefill($new_image, 0, 0, imagecolorallocatealpha($new_image, 255, 255, 255, 127)); // Works but horrible quality
    }

    imagecopyresampled($new_image, $this->image, 0, 0, 0, 0, $width, $height, $this->getWidth(), $this->getHeight());
    $this->image = $new_image;
    unset($new_image);
}

The third fix actually replaces the transparency with white but the quality is so bad I can't use it.

My Question:

I'm hoping I missed something but if not is there a way to do this? I am not wanting to use timThumb, phpThumb, or the class.upload.php script. Mainly because of the system I am working with and the way timthumb and phpthumb works is not ideal. The class.upload.php would be too much work to change all the scripts that use this... (old system that I got tossed on...)

Thanks for any help you can provide! :)

Edit:

I was finally able to get png transparency to work by doing this (answer found here):

function resize($width, $height) {
    $new_image = imagecreatetruecolor($width, $height);

    /* Check if this image is PNG or GIF, then set if Transparent*/
    if(($this->image_type == IMAGETYPE_GIF) || ($this->image_type==IMAGETYPE_PNG)){
        imagealphablending($new_image, false);
        imagesavealpha($new_image,true);
        $transparent = imagecolorallocatealpha($new_image, 255, 255, 255, 127);
        imagefilledrectangle($new_image, 0, 0, $width, $height, $transparent);
    }

    imagecopyresampled($new_image, $this->image, 0, 0, 0, 0, $width, $height, $this->getWidth(), $this->getHeight());
    $this->image = $new_image;
    unset($new_image);
}

I still need to figure out how to do this fix for gif

Community
  • 1
  • 1
Jeremy
  • 1,878
  • 2
  • 30
  • 54

1 Answers1

0

After being in a similar pickle, I found ImageMagick to work the best. Not sure how this will play with your GD functions, so you may have to convert the rest over to use IMagick as well.

/**
 * Resize the image
 * @param $width
 * @param $height
 */
function resize($width, $height) {
    $new_image = new Imagick();
    $new_image->newImage($width, $height, new ImagickPixel('transparent'));
    $new_image->setImageFormat("png");
    $new_image->compositeImage( $this->image, Imagick::COMPOSITE_OVER, 0, 0 );
    $this->image = $new_image;
    unset($new_image);
}

Edit: You could possibly use something similar to this answer in converting the GD image to imagick.

Community
  • 1
  • 1
jmgardn2
  • 981
  • 2
  • 8
  • 21
  • Thanks for the suggestion. I had to enable the extension but it was still throwing errors. I was able to fix the png transparency issue from this post: http://stackoverflow.com/a/6401135/650206 Gifs are not used often but I will still be looking for that fix. Thanks for your help! – Jeremy Jun 07 '13 at 19:36