上传和调整 Png 大小会产生黑色背景图像
Posted
技术标签:
【中文标题】上传和调整 Png 大小会产生黑色背景图像【英文标题】:Uploading and resizing Png produces a black background image 【发布时间】:2015-08-12 12:39:15 【问题描述】:我正在使用以下类来裁剪、调整大小和上传图像。但是当我尝试上传文件时,它会生成一个黑色背景的 png 图像。
我尝试了很多方法,例如 imageAlphaBlending 和 imageSaveAlpha,但都没有解决我的问题
我正在使用此链接中的 ImageManipulator.php https://gist.github.com/philBrown/880506
请告诉我如何解决这个问题。谢谢你
`
/**
* @var int
*/
protected $height;
/**
* @var resource
*/
protected $image;
/**
* Image manipulator constructor
*
* @param string $file OPTIONAL Path to image file or image data as string
* @return void
*/
public function __construct($file = null)
if (null !== $file)
if (is_file($file))
$this->setImageFile($file);
else
$this->setImageString($file);
/**
* Set image resource from file
*
* @param string $file Path to image file
* @return ImageManipulator for a fluent interface
* @throws InvalidArgumentException
*/
public function setImageFile($file)
if (!(is_readable($file) && is_file($file)))
throw new InvalidArgumentException("Image file $file is not readable");
if (is_resource($this->image))
imagedestroy($this->image);
list ($this->width, $this->height, $type) = getimagesize($file);
switch ($type)
case IMAGETYPE_GIF :
$this->image = imagecreatefromgif($file);
break;
case IMAGETYPE_JPEG :
$this->image = imagecreatefromjpeg($file);
break;
case IMAGETYPE_PNG :
$this->image = imagecreatefrompng($file);
break;
default :
throw new InvalidArgumentException("Image type $type not supported");
return $this;
/**
* Set image resource from string data
*
* @param string $data
* @return ImageManipulator for a fluent interface
* @throws RuntimeException
*/
public function setImageString($data)
if (is_resource($this->image))
imagedestroy($this->image);
if (!$this->image = imagecreatefromstring($data))
throw new RuntimeException('Cannot create image from data string');
$this->width = imagesx($this->image);
$this->height = imagesy($this->image);
return $this;
/**
* Resamples the current image
*
* @param int $width New width
* @param int $height New height
* @param bool $constrainProportions Constrain current image proportions when resizing
* @return ImageManipulator for a fluent interface
* @throws RuntimeException
*/
public function resample($width, $height, $constrainProportions = true)
if (!is_resource($this->image))
throw new RuntimeException('No image set');
if ($constrainProportions)
if ($this->height >= $this->width)
$width = round($height / $this->height * $this->width);
else
$height = round($width / $this->width * $this->height);
$temp = imagecreatetruecolor($width, $height);
imagecopyresampled($temp, $this->image, 0, 0, 0, 0, $width, $height, $this->width, $this->height);
return $this->_replace($temp);
/**
* Enlarge canvas
*
* @param int $width Canvas width
* @param int $height Canvas height
* @param array $rgb RGB colour values
* @param int $xpos X-Position of image in new canvas, null for centre
* @param int $ypos Y-Position of image in new canvas, null for centre
* @return ImageManipulator for a fluent interface
* @throws RuntimeException
*/
public function enlargeCanvas($width, $height, array $rgb = array(), $xpos = null, $ypos = null)
if (!is_resource($this->image))
throw new RuntimeException('No image set');
$width = max($width, $this->width);
$height = max($height, $this->height);
$temp = imagecreatetruecolor($width, $height);
if (count($rgb) == 3)
$bg = imagecolorallocate($temp, $rgb[0], $rgb[1], $rgb[2]);
imagefill($temp, 0, 0, $bg);
if (null === $xpos)
$xpos = round(($width - $this->width) / 2);
if (null === $ypos)
$ypos = round(($height - $this->height) / 2);
imagecopy($temp, $this->image, (int) $xpos, (int) $ypos, 0, 0, $this->width, $this->height);
return $this->_replace($temp);
/**
* Crop image
*
* @param int|array $x1 Top left x-coordinate of crop box or array of coordinates
* @param int $y1 Top left y-coordinate of crop box
* @param int $x2 Bottom right x-coordinate of crop box
* @param int $y2 Bottom right y-coordinate of crop box
* @return ImageManipulator for a fluent interface
* @throws RuntimeException
*/
public function crop($x1, $y1 = 0, $x2 = 0, $y2 = 0)
if (!is_resource($this->image))
throw new RuntimeException('No image set');
if (is_array($x1) && 4 == count($x1))
list($x1, $y1, $x2, $y2) = $x1;
$x1 = max($x1, 0);
$y1 = max($y1, 0);
$x2 = min($x2, $this->width);
$y2 = min($y2, $this->height);
$width = $x2 - $x1;
$height = $y2 - $y1;
$temp = imagecreatetruecolor($width, $height);
imagecopy($temp, $this->image, 0, 0, $x1, $y1, $width, $height);
return $this->_replace($temp);
/**
* Replace current image resource with a new one
*
* @param resource $res New image resource
* @return ImageManipulator for a fluent interface
* @throws UnexpectedValueException
*/
protected function _replace($res)
if (!is_resource($res))
throw new UnexpectedValueException('Invalid resource');
if (is_resource($this->image))
imagedestroy($this->image);
$this->image = $res;
$this->width = imagesx($res);
$this->height = imagesy($res);
return $this;
/**
* Save current image to file
*
* @param string $fileName
* @return void
* @throws RuntimeException
*/
public function save($fileName, $type = IMAGETYPE_JPEG)
$dir = dirname($fileName);
if (!is_dir($dir))
if (!mkdir($dir, 0755, true))
throw new RuntimeException('Error creating directory ' . $dir);
try
switch ($type)
case IMAGETYPE_GIF :
if (!imagegif($this->image, $fileName))
throw new RuntimeException;
break;
case IMAGETYPE_PNG :
if (!imagepng($this->image, $fileName))
throw new RuntimeException;
break;
case IMAGETYPE_JPEG :
default :
if (!imagejpeg($this->image, $fileName, 95))
throw new RuntimeException;
catch (Exception $ex)
throw new RuntimeException('Error saving image file to ' . $fileName);
/**
* Returns the GD image resource
*
* @return resource
*/
public function getResource()
return $this->image;
/**
* Get current image resource width
*
* @return int
*/
public function getWidth()
return $this->width;
/**
* Get current image height
*
* @return int
*/
public function getHeight()
return $this->height;
`
【问题讨论】:
对echo "<script>alert('dfds')</script>";
的加入感到好奇~ 仅仅是为了尝试调试吗?我猜想在创建 png 时会导致错误...
对不起..我正在尝试调试。但这不是真正的问题。请忽略此行
请任何人告诉我一个解决方案。
您是否更改了图像类的副本以合并其他用户建议的修复(朝向页面底部)?
【参考方案1】:
我终于找到了解决这个问题的办法
我们需要修改重采样和这些额外的行
`$temp = imagecreatetruecolor($width, $height);
// PNG/GIF Transparency
imagealphablending($temp, false);
imagesavealpha($temp,true);
$transparent = imagecolorallocatealpha($temp, 255, 255, 255, 127);
imagefilledrectangle($temp, 0, 0, $width, $height, $transparent);
imagecopyresampled($temp, $this->image, 0, 0, 0, 0, $width, $height, $this->width, $this->height);`
在保存功能中,我们还需要添加一些额外的行,例如 case IMAGETYPE_PNG :
imagealphablending($this->image, false);
imagesavealpha($this->image,true);
内
这将解决问题。感谢大家为解决这个问题所做的努力。
【讨论】:
【参考方案2】:正确的做法是在你的 setImageFile 函数中,在$this->image = imagecreatefrompng($file);
之后添加这些行:
imageAlphaBlending($this->image, true);
imageSaveAlpha($this-image, true);
另外,在保存函数内部,case IMAGETYPE_PNG :
之后添加:
header('Content-Type: image/png');
【讨论】:
对不起,我回答错了问题。真对不起。我编辑了答案,现在应该可以正常工作了以上是关于上传和调整 Png 大小会产生黑色背景图像的主要内容,如果未能解决你的问题,请参考以下文章