PHP调整图像大小并保存为透明PNG

Posted

技术标签:

【中文标题】PHP调整图像大小并保存为透明PNG【英文标题】:PHP Resize image and save as transparent PNG 【发布时间】:2016-02-04 07:25:23 【问题描述】:

我做错了什么?它适用于 jpg 和 gif,但不适用于 transparent png 文件。检查了其他一些问题,但不明白,因为我对 php 不是很好。如果有人能解决这个问题,我将不胜感激!

<?php
   # ========================================================================#
   #  Requires : Requires PHP5, GD library.
   #  Usage Example:
   #                     include("resize_class.php");
   #                     $resizeObj = new resize('images/cars/large/input.jpg');
   #                     $resizeObj -> resizeImage(150, 100, 0);
   #                     $resizeObj -> saveImage('images/cars/large/output.jpg', 100);
   # ========================================================================#


        class resize
        
            // *** Class variables
            private $image;
            private $width;
            private $height;
            private $imageResized;

            function __construct($fileName)
            
                // *** Open up the file
                $this->image = $this->openImage($fileName);

                // *** Get width and height
                $this->width  = imagesx($this->image);
                $this->height = imagesy($this->image);
            

            ## --------------------------------------------------------

            private function openImage($file)
            
                // *** Get extension
                $extension = strtolower(strrchr($file, '.'));

                switch($extension)
                
                    case '.jpg':
                    case '.jpeg':
                        $img = @imagecreatefromjpeg($file);
                        break;
                    case '.gif':
                        $img = @imagecreatefromgif($file);
                        break;
                    case '.png':
                        $img = @imagecreatefrompng($file);
                        break;
                    default:
                        $img = false;
                        break;
                
                return $img;
            

            ## --------------------------------------------------------

            public function resizeImage($newWidth, $newHeight, $option="auto")
            
                // *** Get optimal width and height - based on $option
                $optionArray = $this->getDimensions($newWidth, $newHeight, $option);

                $optimalWidth  = $optionArray['optimalWidth'];
                $optimalHeight = $optionArray['optimalHeight'];


                // *** Resample - create image canvas of x, y size
                $this->imageResized = imagecreatetruecolor($optimalWidth, $optimalHeight);
                imagecopyresampled($this->imageResized, $this->image, 0, 0, 0, 0, $optimalWidth, $optimalHeight, $this->width, $this->height);


                // *** if option is 'crop', then crop too
                if ($option == 'crop') 
                    $this->crop($optimalWidth, $optimalHeight, $newWidth, $newHeight);
                
            

            ## --------------------------------------------------------

            private function getDimensions($newWidth, $newHeight, $option)
            

               switch ($option)
                
                    case 'exact':
                        $optimalWidth = $newWidth;
                        $optimalHeight= $newHeight;
                        break;
                    case 'portrait':
                        $optimalWidth = $this->getSizeByFixedHeight($newHeight);
                        $optimalHeight= $newHeight;
                        break;
                    case 'landscape':
                        $optimalWidth = $newWidth;
                        $optimalHeight= $this->getSizeByFixedWidth($newWidth);
                        break;
                    case 'auto':
                        $optionArray = $this->getSizeByAuto($newWidth, $newHeight);
                        $optimalWidth = $optionArray['optimalWidth'];
                        $optimalHeight = $optionArray['optimalHeight'];
                        break;
                    case 'crop':
                        $optionArray = $this->getOptimalCrop($newWidth, $newHeight);
                        $optimalWidth = $optionArray['optimalWidth'];
                        $optimalHeight = $optionArray['optimalHeight'];
                        break;
                
                return array('optimalWidth' => $optimalWidth, 'optimalHeight' => $optimalHeight);
            

            ## --------------------------------------------------------

            private function getSizeByFixedHeight($newHeight)
            
                $ratio = $this->width / $this->height;
                $newWidth = $newHeight * $ratio;
                return $newWidth;
            

            private function getSizeByFixedWidth($newWidth)
            
                $ratio = $this->height / $this->width;
                $newHeight = $newWidth * $ratio;
                return $newHeight;
            

            private function getSizeByAuto($newWidth, $newHeight)
            
                if ($this->height < $this->width)
                // *** Image to be resized is wider (landscape)
                
                    $optimalWidth = $newWidth;
                    $optimalHeight= $this->getSizeByFixedWidth($newWidth);
                
                elseif ($this->height > $this->width)
                // *** Image to be resized is taller (portrait)
                
                    $optimalWidth = $this->getSizeByFixedHeight($newHeight);
                    $optimalHeight= $newHeight;
                
                else
                // *** Image to be resizerd is a square
                
                    if ($newHeight < $newWidth) 
                        $optimalWidth = $newWidth;
                        $optimalHeight= $this->getSizeByFixedWidth($newWidth);
                     else if ($newHeight > $newWidth) 
                        $optimalWidth = $this->getSizeByFixedHeight($newHeight);
                        $optimalHeight= $newHeight;
                     else 
                        // *** Sqaure being resized to a square
                        $optimalWidth = $newWidth;
                        $optimalHeight= $newHeight;
                    
                

                return array('optimalWidth' => $optimalWidth, 'optimalHeight' => $optimalHeight);
            

            ## --------------------------------------------------------

            private function getOptimalCrop($newWidth, $newHeight)
            

                $heightRatio = $this->height / $newHeight;
                $widthRatio  = $this->width /  $newWidth;

                if ($heightRatio < $widthRatio) 
                    $optimalRatio = $heightRatio;
                 else 
                    $optimalRatio = $widthRatio;
                

                $optimalHeight = $this->height / $optimalRatio;
                $optimalWidth  = $this->width  / $optimalRatio;

                return array('optimalWidth' => $optimalWidth, 'optimalHeight' => $optimalHeight);
            

            ## --------------------------------------------------------

            private function crop($optimalWidth, $optimalHeight, $newWidth, $newHeight)
            
                // *** Find center - this will be used for the crop
                $cropStartX = ( $optimalWidth / 2) - ( $newWidth /2 );
                $cropStartY = ( $optimalHeight/ 2) - ( $newHeight/2 );

                $crop = $this->imageResized;
                //imagedestroy($this->imageResized);

                // *** Now crop from center to exact requested size
                $this->imageResized = imagecreatetruecolor($newWidth , $newHeight);
                imagecopyresampled($this->imageResized, $crop , 0, 0, $cropStartX, $cropStartY, $newWidth, $newHeight , $newWidth, $newHeight);
            

            ## --------------------------------------------------------

            public function saveImage($savePath, $imageQuality="100")
            
                // *** Get extension
                $extension = strrchr($savePath, '.');
                   $extension = strtolower($extension);

                switch($extension)
                
                    case '.jpg':
                    case '.jpeg':
                        if (imagetypes() & IMG_JPG) 
                            imagejpeg($this->imageResized, $savePath, $imageQuality);
                        
                        break;

                    case '.gif':
                        if (imagetypes() & IMG_GIF) 
                            imagegif($this->imageResized, $savePath);
                        
                        break;

                    case '.png':
                        // *** Scale quality from 0-100 to 0-9
                        $scaleQuality = round(($imageQuality/100) * 9);

                        // *** Invert quality setting as 0 is best, not 9
                        $invertScaleQuality = 9 - $scaleQuality;

                        if (imagetypes() & IMG_PNG) 
                             imagepng($this->imageResized, $savePath, $invertScaleQuality);
                        
                        break;

                    // ... etc

                    default:
                        // *** No extension - No save.
                        break;
                

                imagedestroy($this->imageResized);
            


            ## --------------------------------------------------------

        
?>

【问题讨论】:

欢迎来到 ***,请查看如何编写 MCEV 问题并相应地修改您的问题。 【参考方案1】:

看看这个函数:

function resizePng($im, $dst_width, $dst_height) 
        $width = imagesx($im);
        $height = imagesy($im);

        $newImg = imagecreatetruecolor($dst_width, $dst_height);

        imagealphablending($newImg, false);
        imagesavealpha($newImg, true);
        $transparent = imagecolorallocatealpha($newImg, 255, 255, 255, 127);
        imagefilledrectangle($newImg, 0, 0, $width, $height, $transparent);
        imagecopyresampled($newImg, $im, 0, 0, 0, 0, $dst_width, $dst_height, $width, $height);

        return $newImg;
    

在这篇文章中:How do I resize pngs with transparency in PHP?

也许可以帮到你!运气!

【讨论】:

添加了它,但它仍然不起作用。 imagealphablending($this->image, false); imagesavealpha($this->image, true); $transparent = imagecolorallocatealpha($this->image, 255, 255, 255, 127); imagefilledrectangle($this->image, 0, 0, $width, $height, $transparent); $this->imageResized = imagecreatetruecolor($optimalWidth, $optimalHeight); imagecopyresampled($this->imageResized, $this->image, 0, 0, 0, 0, $optimalWidth, $optimalHeight, $this->width, $this->height);【参考方案2】:

替换resizeImages函数

        public function resizeImage($newWidth, $newHeight, $option="auto")
        
            // *** Get optimal width and height - based on $option
            $optionArray = $this->getDimensions($newWidth, $newHeight, $option);

            $optimalWidth  = $optionArray['optimalWidth'];
            $optimalHeight = $optionArray['optimalHeight'];


            // *** Resample - create image canvas of x, y size
            $this->imageResized = imagecreatetruecolor($optimalWidth, $optimalHeight);

            // *** Support transparent png
            if(imagetypes() & IMG_PNG)
                imagealphablending($this->imageResized, false);
                imagesavealpha($this->imageResized,true);
                $transparent = imagecolorallocatealpha($this->imageResized, 255, 255, 255, 127);
                imagefilledrectangle($this->imageResized, 0, 0, $optimalWidth, $optimalHeight, $transparent);
            

            imagecopyresampled($this->imageResized, $this->image, 0, 0, 0, 0, $optimalWidth, $optimalHeight, $this->width, $this->height);


            // *** if option is 'crop', then crop too
            if ($option == 'crop') 
                $this->crop($optimalWidth, $optimalHeight, $newWidth, $newHeight);
            
        

【讨论】:

以上是关于PHP调整图像大小并保存为透明PNG的主要内容,如果未能解决你的问题,请参考以下文章

将透明 PNG 保存为透明 GIF

带有透明PNG的imagetruecolortopalette的PHP错误结果

如何改进我的 php 图像调整器以支持 alpha png 和透明 GIF

使用PHP的GDlib imagecopyresampled时可以保留PNG图像透明度吗?

如何在 PHP 中调整具有透明度的 png 大小?

使用gd在php中调整图像大小后的黑色背景