I've set about using image.module to give me dynamic resizing and have discovered that it doesn't handle transparent pngs at all well. It makes the transparent part black. I've narrowed this down to the functions image.inc provides.

Searching google reveals that GD does not support this funcitonality very well. However on this site; http://forums.devnetwork.net/viewtopic.php?t=43357&
I found a workaround for this limited functionality.

function image_gd_resize($source, $destination, $width, $height) {
  if (!file_exists($source)) {
    return false;
  }

  $info = image_get_info($source);
  if (!$info) {
    return false;
  }

  $im = image_gd_open($source, $info['extension']);
  if (!$im) {
    return false;
  }

  //New line to use new function
  //$res = imageCreateTrueColor($width, $height);
  $res = imagecreatetruecolortransparent($width, $height);
  imageCopyResampled($res, $im, 0, 0, 0, 0, $width, $height, $info['width'], $info['height']);
  $result = image_gd_close($res, $destination, $info['extension']);

  imageDestroy($res);
  imageDestroy($im);

  return $result;
}

function imagecreatetruecolortransparent($x,$y) {
  $i = imagecreatetruecolor($x,$y);
  $b = imagecreatefromstring(base64_decode(blankpng()));
  imagealphablending($i,false);
  imagesavealpha($i,true);
  imagecopyresized($i,$b,0,0,0,0,$x,$y,imagesx($b),imagesy($b));
  return $i;
}

function blankpng() {
  $c  = "iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAYAAACM/rhtAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29m";
  $c .= "dHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAADqSURBVHjaYvz//z/DYAYAAcTEMMgBQAANegcCBNCg";
  $c .= "dyBAAA16BwIE0KB3IEAADXoHAgTQoHcgQAANegcCBNCgdyBAAA16BwIE0KB3IEAADXoHAgTQoHcgQAAN";
  $c .= "egcCBNCgdyBAAA16BwIE0KB3IEAADXoHAgTQoHcgQAANegcCBNCgdyBAAA16BwIE0KB3IEAADXoHAgTQ";
  $c .= "oHcgQAANegcCBNCgdyBAAA16BwIE0KB3IEAADXoHAgTQoHcgQAANegcCBNCgdyBAAA16BwIE0KB3IEAA";
  $c .= "DXoHAgTQoHcgQAANegcCBNCgdyBAgAEAMpcDTTQWJVEAAAAASUVORK5CYII=";

  return $c;
}

The code above is the necessary functions and the changed .inc function. I cannot make patches :-/ sorry.

I've tested this and it works fine. I get nice transparent resized pngs. Since this is a workaround for GD based shortcomings i'm not sure of it's status within drupal bugs, but here it is.

Thanks
Adam

Comments

Stefan Nagtegaal’s picture

Status: Needs work » Active

I will investigate this option tonight..
And provde a patch when this is needed..

darren oh’s picture

Version: x.y.z » 4.7.0
Assigned: Unassigned » darren oh
Status: Active » Reviewed & tested by the community
StatusFileSize
new1.55 KB

The new code is great! I really appreciate it since I can't get ImageMagick to work. Here is the patch.

dries’s picture

I'd prefer not have code like this. Maybe this got fixed in newer versions of PHP?

drumm’s picture

Status: Reviewed & tested by the community » Needs work

Please remove the debug code.

darren oh’s picture

Status: Needs work » Needs review
StatusFileSize
new1.46 KB

I removed the comments. I hope this is what you meant.

Stefan Nagtegaal’s picture

I'm not sure your way is the cleanest and most elegant one.
I think there is a better way to solve this.. Let me get back to this issue after some investigation and testing..

dries’s picture

-1 on this patch. It's a PHP issue, IMO.

killes@www.drop.org’s picture

Status: Needs review » Closed (won't fix)

ack

darren oh’s picture

Status: Closed (won't fix) » Needs work

I am now using PHP5 and can confirm that the patch is still necessary. I don't think this is a PHP issue because GD2 obviously does support transparency with this patch. I agree that the code should be simplified.

darren oh’s picture

Title: Image.inc does not support resizing of transparent PNGs » GD2 Replaces Transparency with Black When Resizing
darren oh’s picture

Assigned: darren oh » Unassigned

It may be a while before I can work on this.

darren oh’s picture

I see now why this is a PHP issue. The patch creates a function that really should be provided by PHP.

darren oh’s picture

I found a method for preserving transparency that uses existing PHP functions described in the PHP manual:

This is another approach to get an initially transparent truecolor canvas and in comparison to the one below it does not declare black to be transparent (which might be okay on indexed-color images and unless you want to draw in black) ...

$im = imagecreatetruecolor( $w, $h );
imagealphablending( $im, false );
$col = imagecolorallocate( $im, 0, 0, 0, 127 );
imagefilledrectangle( $im, 0, 0, $w, $h, $col );
imagealphablending( $im, true );

Without disabling blending mode this would paint transparent rectangle over current background thus not changing anything. Nevertheless blending mode is required e.g. to get proper results from using imagettftext ... that's why it is enabled after filling, again.

Don't miss to disable blending mode and enable savealpha prior to generating a PNG ...

imagealphablending( $im, false );
imagesavealpha( $im, true );
imagepng( $im );

darren oh’s picture

Title: GD2 Replaces Transparency with Black When Resizing » Preserving transparency when resizing with GD2
Version: 4.7.0 » x.y.z
Status: Needs work » Needs review
StatusFileSize
new593 bytes

I found that the problem is that the default background is black. I added four lines to make the background transparent and preserve transparency.

Stefan Nagtegaal’s picture

I will test and review this patch later. Probably tomorrow..

Steef

Stefan Nagtegaal’s picture

StatusFileSize
new991 bytes

okay, i tested this it is indeed working..

Because the extra lines of code do only work for transluscent png's, I added a check for if ($info['extension'] == 'png') and did the extra image alpha allocation in there.
Another benefit for this check is that the used functions imagealphablending() are quite heavy for a server to handle. So doing that for every uploaded image is nonsense..

IMO this is RTBC, but I let someone else decide on this..

To test:
Use some (partially) transparent png-file to upload it to drupal and make use of the img-tag inside your body to display the image..

Without this patch, the transluscent/transparent parts of the image will become black and with the patch applied, every transluscent/transparent pixel will be handled as expected for the end user.

I really encourage you guys to review and apply this patch.
If any more work has to be done to get this in, let me know and I'll try to take care of it..

Steef

Stefan Nagtegaal’s picture

StatusFileSize
new23.34 KB

For people to test, I added a transluscent png to this issue so it's easier to test.

Stefan Nagtegaal’s picture

Status: Needs review » Reviewed & tested by the community

I'm using this for 3 days, uploading and resizing/rotating/manipulating images all through drupal and so I dare to set this RTBC.

Please apply..

dries’s picture

Status: Reviewed & tested by the community » Needs work

Tabs? Coding style needs work.

darren oh’s picture

Status: Needs work » Reviewed & tested by the community
StatusFileSize
new813 bytes

Cleaned up patch.

Stefan Nagtegaal’s picture

This works and coding style looks okay now..

(BTW sorry for the coding style things, I thought my editor was setup the right way for using spaces instead of tabs,but I was obviously wrong :-( )

dries’s picture

Status: Reviewed & tested by the community » Fixed

Committed to CVS HEAD. Thanks.

killes@www.drop.org’s picture

backported

Anonymous’s picture

Status: Fixed » Closed (fixed)