0

I m trying to remove the background of an image and make it transparent using PHP without using any 3rd party plugins like ImageMagick or another.

I came across this code in SO itself which promised to echo out transparent background image as result. After trying it did work but I had to define every color in RGB that need to be removed. This is a huge setback as the background colors may vary from image to image as I upload.

The code I tried:

<?php
$_filename='https://vdofy.harryatwork.com/dev/images-main/images/16330699786156ab99b0c44.png';

$_backgroundColour='0,0,0';
$_img = imagecreatefrompng($_filename);
$_backgroundColours = explode(',', $_backgroundColour);
$_removeColour = imagecolorallocate($_img, (int)$_backgroundColours[0], (int)$_backgroundColours[1], (int)$_backgroundColours[2]);
imagecolortransparent($_img, $_removeColour);
imagesavealpha($_img, true);
$_transColor = imagecolorallocatealpha($_img, 0, 0, 0, 127);
imagefill($_img, 0, 0, $_transColor);
imagepng($_img, $_SERVER['DOCUMENT_ROOT']."/bg_removed.png");
    
?>

Can you guys please share your expertise on making this work?

  • 1
    I would have thought `imagecreatefrompng` is expecting a `.png` input file, so that call would fail to load a `.jpg` – Nigel Ren Oct 04 '21 at 06:38
  • @NigelRen tried with a png as well, nothing on the screen. – Ambiguous Turtle Oct 04 '21 at 06:41
  • Does the file `$_filename` contain the result you are after (this is where the call to `imagepng` will store the output if you specify it) – Nigel Ren Oct 04 '21 at 06:44
  • @NigelRen no, when I echo the `$_filename` it simply echos the original image url. – Ambiguous Turtle Oct 04 '21 at 06:48
  • You are trying to _store_ the image to the same URL contained in `$_filename`, that you read it from - that won't work, the HTTP wrapper only allows reading, not writing. You need to store the new image in the local file system. If you need it on a different server - then you will have to upload it to there afterwards. – CBroe Oct 04 '21 at 06:48
  • @CBroe ok, first of all, Big fan bro. been following you for a long time. And as per my understanding, you are saying is that the above code works but I need to download the generated image into a folder and call it back to echo it instead of re-assigning it to the same var.. right..? – Ambiguous Turtle Oct 04 '21 at 06:55
  • He means you need to pass a local path to the function in order to store the image e.g. `imagepng($_img, __DIR__ . '/test.png');` – DarkBee Oct 07 '21 at 07:06

2 Answers2

3

Final answer

Your prerequisites WITHOUT USING ANY PLUGIN gives as the only option to look for a pixel color based answer. But it is a bad way, because you don't have "color block" images and you can't be sure that a color you're removing is not also in the foreground you want to keep.

The distinction between foreground and background is a human notion and should be processed by an very "clever" plugin. ImageMagick himself fails on your example image :

enter image description here


First answer

Here you can remove one of the pixel colors, I arbitrary get one of them and make it transparent with this code :

<?php

$_filename='https://vdofy.harryatwork.com/dev/images-main/images/16330699786156ab99b0c44.png';
$im = imagecreatefrompng($_filename);
$remove = imagecolorallocate($im, 208, 216, 218);

imagecolortransparent($im, $remove);

imagepng($im, $_SERVER['DOCUMENT_ROOT']."/philippe-test.png");
imagedestroy($im);

?>
<body style="background-color: rebeccapurple;">
  <img src="/philippe-test.png">
</body>

But I'm afraid you have to make it with all the colors to remove, there is no wizard to remove the "background", which is a subjective notion ;)

Philippe
  • 1,134
  • 12
  • 22
  • But the background color will change from image to image. what we can do on those scenarios – Ambiguous Turtle Oct 08 '21 at 05:31
  • Yes indeed ! Determining what is the "foreground" in an image can't be solved by removing colors. Cropping what Humans consider as the most interesting part of an image is A.I. hard work. – Philippe Oct 08 '21 at 08:13
2

If the background color is different in other images, you could use imagecolorat.

Specify a pixel ($x and $y in the following code), that has same color as background:

<?php

$_filename='https://vdofy.harryatwork.com/dev/images-main/images/16330699786156ab99b0c44.png';
$im = imagecreatefrompng($_filename);

// coordinates of a pixel that has background color
$x = 10;
$y = 10;

$rgb = imagecolorat($im, $x, $y);
$r = ($rgb >> 16) & 0xFF;
$g = ($rgb >> 8) & 0xFF;
$b = $rgb & 0xFF;

$remove = imagecolorallocate($im, $r, $g, $b);

imagecolortransparent($im, $remove);

imagepng($im, $_SERVER['DOCUMENT_ROOT']."/philippe-test.png");
imagedestroy($im);

?>

<body style="background-color: rebeccapurple;">
  <img src="/philippe-test.png">
</body>

See https://www.php.net/manual/en/function.imagecolorat.php

schmauch
  • 630
  • 1
  • 7
  • 10