7

When I try to crop transparant area of an image, its get to keep it original size, and the transparant areas are turned black.

If i run this code:

<?php
    // Create a 300x300px transparant image with a 100px wide red circle in the middle
    $i = imagecreatetruecolor(300, 300);
    imagealphablending($i, FALSE);
    imagesavealpha($i, TRUE);
    $transparant = imagecolorallocatealpha($i, 0xDD, 0xDD, 0xDD, 0x7F);
    imagefill($i, 0, 0, $transparant);
    $red = imagecolorallocate($i, 0xFF, 0x0, 0x0);
    imagefilledellipse($i, 150, 150, 100, 100, $red);
    imagepng($i, "red_300.png");

    // Crop away transparant parts and save
    $i2 = imagecropauto($i, IMG_CROP_TRANSPARENT);
    imagepng($i2, "red_crop_trans.png");
    imagedestroy($i2);

    // Crop away bg-color parts and save
    $i2 = imagecropauto($i, IMG_CROP_SIDES);
    imagepng($i2, "red_crop_sides.png");
    imagedestroy($i2);

    // clean up org image
    imagedestroy($i);

I end up with a red_crop_trans.png image that is a 300x300px black image with an 100x100px red circle in it. And a red_crop_sides.png that is a 100x100px black image with a 100x100px red circle in it.

Why is red_crop_trans.png not croped to 100x100px? and why is the background of both images black? And how do I crop them while keeping the transparace?

Aniket Sahrawat
  • 12,410
  • 3
  • 41
  • 67
Puggan Se
  • 5,738
  • 2
  • 22
  • 48

1 Answers1

3

It took me a while to figure out what exactly was going on. It turned out $i2 = imagecropauto($i, IMG_CROP_TRANSPARENT); was returning false instead of true. According to the docs:

imagecropauto() returns FALSE when there is either nothing to crop or the whole image would be cropped.

So instead of IMG_CROP_TRANSPARENT I used IMG_CROP_DEFAULT:

Attempts to use IMG_CROP_TRANSPARENT and if it fails it falls back to IMG_CROP_SIDES.

This gave me the expected result. Now I didn't get any black backgrounds myself. But it's a known issue so the solution was quite easily found:

imagecolortransparent($i, $transparant); // Set background transparent

And that brings me to the final completed code:

<?php
    // Create a 300x300px transparant image with a 100px wide red circle in the middle
    $i = imagecreatetruecolor(300, 300);
    imagealphablending($i, FALSE);
    imagesavealpha($i, TRUE);
    $transparant = imagecolorallocatealpha($i, 0xDD, 0xDD, 0xDD, 0x7F);
    imagecolortransparent($i, $transparant); // Set background transparent
    imagefill($i, 0, 0, $transparant);
    $red = imagecolorallocate($i, 0xFF, 0x0, 0x0);
    imagefilledellipse($i, 150, 150, 100, 100, $red);
    imagepng($i, "red_300.png");

    // Crop away transparant parts and save
    $i2 = imagecropauto($i, IMG_CROP_DEFAULT); //Attempts to use IMG_CROP_TRANSPARENT and if it fails it falls back to IMG_CROP_SIDES.
    imagepng($i2, "red_crop_trans.png");
    imagedestroy($i2);

    // Crop away bg-color parts and save
    $i2 = imagecropauto($i, IMG_CROP_SIDES);
    imagepng($i2, "red_crop_sides.png");
    imagedestroy($i2);

    // clean up org image
    imagedestroy($i);

?>
icecub
  • 8,615
  • 6
  • 41
  • 70
  • 1
    That made a diferens, but didn't solve it, now IMG_CROP_TRANSPARENT also returns a 100x100, but still with black background. But if the code works for you, then there something wrong with php or the libraries, are you also running Ubuntu? if not maybe its a Ubuntu related problem. – Puggan Se Nov 12 '16 at 11:02
  • @PugganSe It doesn't sound like a Ubuntu issue to me. I tried this on Windows (wamp), but when I search for this problem, it seems to be related with the order of operations in de code. Perhaps you can learn more from this question here: http://stackoverflow.com/questions/2611852/imagecreatefrompng-makes-a-black-background-instead-of-transparent – icecub Nov 12 '16 at 23:18
  • Order of operation? When saving $i it have transparans, next step is the crop, and then another save, can't change that order of operations. – Puggan Se Nov 13 '16 at 09:14
  • @PugganSe I agree. I happen to have a Ubuntu server at my disposal here. It was only installed a few days ago and hasn't been tested yet. But if you want I can fire it up and check if the results are the same as yours on it – icecub Nov 13 '16 at 09:17
  • 1
    So far I testsed on 4 Ubuntu Server 16.04.1, 1 kUbuntu 16.10, and a gentoo-server, if i include your windows-wamp, the 5 ubuntus gives black background, and the other 2 gives transparant images. So no hurry testing it on your ubuntu, but if you need to fire it up for other reasons, your welcome to confirm it. – Puggan Se Nov 13 '16 at 14:14
  • 1
    Reported it as a bug at https://bugs.launchpad.net/ubuntu/+source/apport/+bug/1641307 Also thinking about makeing a workaround with imagecopyresampled() if i can get the offset value somehow: http://stackoverflow.com/questions/40584754/how-to-get-autocrops-offset-and-size – Puggan Se Nov 14 '16 at 08:53
  • If your png transparency goes black it is highly likely that the process it goes through is dropping to 24bit palette. – Vanquished Wombat Apr 01 '18 at 09:53
  • @VanquishedWombat It's currently listed as a bug in Ubuntu with Confirmed status. I have absolutely no idea why Caw would create a bounty on this old question. The problem lies with Ubuntu and not with the GD library. You can try all sorts of PHP code you want, it's not gonna fix issues with an operating system. – icecub Apr 01 '18 at 12:05