0

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

第三个修复实际上用白色代替了透明度,但质量太差了,我不能使用它。

我的问题:

我希望我错过了一些东西,但如果没有,有没有办法做到这一点?我不想使用timThumb, phpThumb, 或class.upload.php脚本。主要是因为我正在使用的系统以及方式timthumbphpthumb工作方式并不理想。更改所有使用它的class.upload.php脚本会做太多的工作......(我被抛弃的旧系统......)

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

编辑:

通过这样做,我终于能够使 png 透明度起作用(在此处找到答案):

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 进行此修复

4

1 回答 1

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 图像转换为 imagick 时使用类似于此答案的内容。

于 2013-06-07T19:18:50.590 回答