如何修复图像重新调整大小的透明度?

时间:2013-06-07 19:09:57

标签: php image-processing

我在SO上发现了很多关于此的问题,但似乎没有解决我的问题。

我需要调整图像大小并将其保存到特定目录。我的下面的课程完全按照我的需要工作,但透明图像除外。透明图像变成黑色,它们应该是透明的。

修改后的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);
    }

}

我已经尝试过这些修复工具,因为我已经在SO和所有强大的Google中找到了这些修补程序:

注意:这些修补程序已添加到resize方法中。

首次修复:

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

第一个修复不会将黑色更改为白色,这会使图像质量非常低。所以这似乎无法正常工作。

第二次修复:

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

第二个修复似乎并没有解决黑色背景问题,而且质量不是太差,但可能更好。

第三次修正:

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

第三个修复实际上用白色替换透明度,但质量太差我无法使用它。

我的问题:

我希望我错过了什么,但如果没有,有没有办法做到这一点?我不想使用timThumbphpThumbclass.upload.php脚本。主要是因为我正在使用的系统以及timthumbphpthumb的工作方式并不理想。 class.upload.php将更改所有使用此脚本的脚本...(我扔掉的旧系统......)

感谢您提供的任何帮助! :)

修改

我终于能够通过这样做获得png透明度(回答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);
}

我仍然需要弄清楚如何为gif

做这个修复

1 个答案:

答案 0 :(得分:0)

在类似的泡菜中,我发现ImageMagick工作得最好。不确定这将如何与您的GD功能一起使用,因此您可能必须将其余部分转换为使用IMagick。

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

编辑: 在将GD图像转换为想象时,你可能会使用与this类似的答案。