Fix for Transparent PNG files for Symfony sfThumbnailPlugin

One of the project I work on uses Symfony 1.4.  I had a client contact me today saying that when they uploaded transparent png files, the resized files were no longer transparent, instead had a black background.  I thought this was strange and knew it had to be something with resizing of the images using sfThumbnail.  The original images were fine, it was only the resized images that no longer had their transparency.

After doing some google searching I came across a number of people with the same issue.  I eventually was led to this post, http://mediumexposure.com/smart-image-resizing-while-preserving-transparency-php-and-gd-library/ which describes how to do a resize while maintaining transparency.  The original sfThumbnail plugin has the following code in the sfGDAdaptor.class.php file (some lines have been removed for brevity):

public function loadFile($thumbnail, $image)
{
  /* ... removed for brevity ... */
  $this->source = $loader($image);
  $this->sourceWidth = $imgData[0];
  $this->sourceHeight = $imgData[1];
  $this->sourceMime = $imgData['mime'];
  $thumbnail->initThumb($this->sourceWidth, $this->sourceHeight, $this->maxWidth, $this->maxHeight, $this>scale, $this->inflate);
 
  $this->thumb = imagecreatetruecolor($thumbnail->getThumbWidth(), $thumbnail->getThumbHeight());
 
  if ($imgData[0] == $this->maxWidth && $imgData[1] == $this->maxHeight)
  {
    $this->thumb = $this->source;
  } else {
    imagecopyresampled($this->thumb, $this->source, 0, 0, 0, 0, $thumbnail->getThumbWidth(), $thumbnail->getThumbHeight(), $imgData[0], $imgData[1]);
  }
 
  /* ... Removed for brevity ... */
}

If you make the following changes, you will now be able to resize transparent png files and keep their transparency.  This will supposedly work for transparent gif files as well, however I have not tried it.  If you have and it works, please leave comment.

public function loadFile($thumbnail, $image)
{
  $this->source = $loader($image);
  $this->sourceWidth = $imgData[0];
  $this->sourceHeight = $imgData[1];
  $this->sourceMime = $imgData['mime'];
  $thumbnail->initThumb($this->sourceWidth, $this->sourceHeight, $this->maxWidth, $this->maxHeight, $this->scale, $this->inflate);
 
  $this->thumb = imagecreatetruecolor($thumbnail->getThumbWidth(), $thumbnail->getThumbHeight());
 
  if ( ($imgData[2] == IMAGETYPE_GIF) || ($imgData[2] == IMAGETYPE_PNG) ) {
    $trnprt_indx = imagecolortransparent($image);
 
    if ($trnprt_indx >= 0) {
      $trnprt_color = imagecolorsforindex($image, $trnprt_indx);
      $transparency = imagecolorallocate($this->thumb, $trnprt_color['red'], $trnprt_color['green'], $trnprt_color['blue']);
      imagefill($this->thumb, 0, 0, $transparency);
      imagecolortransparent($this->thumb, $transparency);
    } elseif ($imgData[2] == IMAGETYPE_PNG) {
      imagealphablending($this->thumb, false);
      $color = imagecolorallocatealpha($this->thumb, 0, 0, 0, 127);
      imagefill($this->thumb, 0, 0, $color);
      imagesavealpha($this->thumb, true);
    }
  }
 
  if ($imgData[0] == $this->maxWidth && $imgData[1] == $this->maxHeight)
  {
    $this->thumb = $this->source;
  } else {
    imagecopyresampled($this->thumb, $this->source, 0, 0, 0, 0, $thumbnail->getThumbWidth(),   $thumbnail->getThumbHeight(), $imgData[0], $imgData[1]);
  }
}

Comments are closed.