43

Hey having some trouble trying to maintain transparency on a png when i create a thumbnail from it, anyone any experience with this? any help would be great, here's what i am currently doing:

$fileName= "../js/ajaxupload/tees/".$fileName;

list($width, $height) = getimagesize($fileName);

$newwidth = 257;
$newheight = 197;

$thumb = imagecreatetruecolor($newwidth, $newheight);
imagealphablending($thumb, true);
$source = imagecreatefrompng($fileName);
imagealphablending($source, true);

imagecopyresized($thumb, $source, 0, 0, 0, 0, $newwidth, $newheight, $width, $height);

imagesavealpha($thumb, true);
imagepng($thumb,$newFilename);
BastardPrince
  • 433
  • 1
  • 4
  • 4

5 Answers5

85

I have had success doing it like this in the past:

$thumb = imagecreatetruecolor($newwidth, $newheight);
imagealphablending($thumb, false);
imagesavealpha($thumb, true);  

$source = imagecreatefrompng($fileName);
imagealphablending($source, true);

imagecopyresampled($thumb, $source, 0, 0, 0, 0, $newwidth, $newheight, $width, $height);

imagepng($thumb,$newFilename);

I found the output image quality much better using imagecopyresampled() than imagecopyresized()

Tom Haigh
  • 57,217
  • 21
  • 114
  • 142
  • that cracked it! much obliged! – BastardPrince Nov 23 '08 at 23:59
  • 1
    Using imagecopyresampled is what finally worked for me, so not only did it improve the quality, but imagecopyresized wouldn't respect the transparency anyways. – benr Dec 13 '11 at 19:37
  • That exact code did not work for me, but changing imagealphablending($thumb, false); to imagealphablending($thumb, true); on line 2 fixed it. – msbg Apr 26 '14 at 19:49
14

Forget the color transparency index, it never works in all rendering products. Instead use an alpha layer mask:

$image = imagecreatetruecolor($size, $size);

imagealphablending($image, false);
imagesavealpha($image, true);

$trans_layer_overlay = imagecolorallocatealpha($image, 220, 220, 220, 127);
imagefill($image, 0, 0, $trans_layer_overlay);
user629089
  • 149
  • 1
  • 2
3

Those functions access the underlying gdlib library, which is a fine toy, but not something that makes for nice results. If you have the option, use imagemagick instead. The downside is that there are currently no good php-bindings, so you need to access it over the shell, which you're usually not allowed on shared hosts.

troelskn
  • 115,121
  • 27
  • 131
  • 155
1

See dycey's answer to "How do I resize...". Essentially, you need to fill the entire background with transparency before you do any other operations.

Community
  • 1
  • 1
Paul Fisher
  • 9,618
  • 5
  • 37
  • 53
  • You don't need to fill the entire background with transparency, but GD isn't great at dealing with opacity unless it's 100% (completely opaque) or 0% (completely transparent) – SteJ Oct 01 '19 at 03:47
1

imagecopyresized does not support transparency properly.

imagecopymerge does, but it doesn't resize.

The solution? You'd probably end up resizing the thing manually.

strager
  • 88,763
  • 26
  • 134
  • 176
  • `imagecopyresampled` is a better solution, particularly for user-submitted images which can't be resized manually prior to upload; I don't feel that this answer is very helpful. – SteJ Oct 01 '19 at 03:42