10

I am trying to downsize some transparents images in PHP with GD, and whenever I do, there is a weird black-ish border that is added around it.

Before before

After enter image description here

Code

<?php
    $image = imagecreatefromstring(file_get_contents('logo.png'));
    $width = imagesx($image);
    $height = imagesy($image);

    $newWidth = $width - 1;
    $newHeight = $height - 1;
    $output = imagecreatetruecolor($newWidth, $newHeight);
    imagecolortransparent($output, imagecolorallocatealpha($output, 0, 0, 0, 127));
    imagealphablending($output, false);
    imagesavealpha($output, true);
    imagecopyresampled($output, $image, 0, 0, 0, 0, $newWidth, $newHeight, $width, $height);

    header('Content-Type: image/png');
    imagepng($output);
?>

It seems that if I change the code for the new dimensions to be the same as the old (removing the - 1), no black borders appear. So the resize is causing the problem.

Does anyone have an idea what might be wrong?

Edit: I just realized it only happens with imagecopyresampled and not imagecopyresized. However, imagecopyresampled gives a far better visual effect and I'd like to make it work if possible.

Alex Turpin
  • 46,743
  • 23
  • 113
  • 145
  • Looks like the anti-aliasing is using black for a matte color. – Brad Nov 15 '11 at 18:23
  • @Brad indeed it does. However, the documentation page says that anti-aliasing is off by default, and that it only comes with the bundled version of GD, which I'm not using. Maybe some other function is causing it but I don't see any other parameters as far as I can tell... – Alex Turpin Nov 15 '11 at 18:39
  • I just realized it only happens with [`imagecopyresampled`](http://php.net/manual/en/function.imagecopyresampled.php) and not [`imagecopyresized`](http://php.net/manual/en/function.imagecopyresized.php). However, `imagecopyresampled` gives a far better visual effect and I'd like to make it work if possible. – Alex Turpin Nov 15 '11 at 19:06
  • @Xeon06 if you find its solution please tell me also. – Ali Nouman Nov 15 '11 at 19:23

1 Answers1

3

I think the problem here is your source image.

What you have is not a true-color PNG with alpha channel, but an indexed-color PNG with a transparent color. This is apparent if you open the image in Photoshop:

Image as seen in Photoshop

This image was created with anti-aliasing already (which gives the yellow text that white-ish border seen here), but when you re-size it, the sub-pixel calculations may go outside of their borders a bit.

I suspect if you fix the image, making it full RGB with an alpha channel, you won't have this problem.

Brad
  • 159,648
  • 54
  • 349
  • 530
  • Thanks for the answer. Would you possibly know of any way to make it work programatically or is it undoable? – Alex Turpin Nov 15 '11 at 19:43
  • The best thing to do would be to get a good source image. This was easy to fix for you in Photoshop. E-mail me at brad@musatcha.com, and I will send you the updated file. – Brad Nov 15 '11 at 20:10
  • thanks very much for your help. The problem is that this is done by our clients on the web interface. I suppose they'll have to make do. Thanks again. – Alex Turpin Nov 15 '11 at 20:12
  • @Xeon06, perhaps you can only accept true-color images? Or, maybe there is a way to convert this image to a full RGB non-indexed image prior to resizing? – Brad Nov 15 '11 at 20:34
  • 1
    that's what I was wondering about, whether there was a way to convert it beforehand. – Alex Turpin Nov 15 '11 at 20:37
  • @Xeon06, What if you did `imagecreatefrompng()`, then `imagesavealpha()`, and then immediately `imagepng()`. No resizing, just open, set alpha saving, and then output? If you take that output, and then resize, do you get the same issue? What if you try `imagesavealpha()` on the source image first? – Brad Nov 15 '11 at 20:42
  • In both cases I get the same issues. – Alex Turpin Nov 15 '11 at 20:51
  • @Xeon06, In that case, I suspect that the image will have to be in an okay format ahead of time. You might be able to script Gimp to do it, but I'd just have a check for true-color image in the first place, and just not accept a file that is an oddball like this. – Brad Nov 15 '11 at 20:59