PHP & GD - transparent background filled with adjacent color

I know that the problems with PHP + GD transparency were beaten to death on this and many other sites, but I followed all the recommendations and I canโ€™t fix my problem.

First, the explanation:

I am trying to overlay one image on top of another. Both of them have transparent areas. Since the demo I know should look a certain way, I'm trying to checkmark the blue arrow shape I created.

Here are two images:

check mark

blue arrow

Now to my code:

I am using the library / API that I created to remove the TINY bit from image editing using PHP + GD. It is still in its infancy, but the corresponding files are:

Base class
Master bootloader
Combined class (poorly named)

I run the code using the following script:

<?php require_once('Image.php'); header("Content-Type: image/png"); $img = new Image(); $over = new Image(); $img->source = "arrow.png"; $over->source = "chk-done_24.png"; $img->Combine->Overlay($over, 20, 20, 0, 0, $over->width, $over->height); $img->output(); $img->clean(); unset($img); ?> 

I expect the result to be something like this:

Combined images

But instead, I get the following:

Square bottom

I would completely understand the problem if the filled area was white or black , but filling with blue just doesn't make any sense to me.

In the combined class I above, I also tried imagecopy , imagecopyresampled and vanilla imagecopymerge , both with similar results.

I have a complete loss.

Edit:

To be clear, my question is: what part of my code is incorrect? Why does it fill the transparent area with color (instead of black or white) and how can I fix it, while maintaining the ability to merge images with transparency?

Update:

Note that when creating a new image object, it calls newImage , which contains the following code:

 $this->handle = imagecreatetruecolor($this->width, $this->height); imagealphablending($this->handle, false); imagesavealpha($this->handle, true); 

It seems to me that this is easy to miss.

+6
source share
1 answer

Note that it doesn't matter that you create a descriptor in newImage and call imagealphablending and imagesavealpha on it, because loadImage throws this descriptor.

The reason this โ€œfillโ€ the transparent area with blue is because it does not fill the transparent area at all. It just completely discards the alpha channel, and the blue color is what is stored in these pixels with alpha zero. Please note that this can be difficult to see in a graphics program, as this program itself can replace fully transparent pixels with black or white.

As for what is wrong with your code, I canโ€™t say for sure, since I donโ€™t get the same results as you when I try to use existing code. But if I changed your loadImage to something like this so that the source images are tied to true color, this works for me:

  private function loadImage() { $img = null; switch( $this->type ) { case 1: $img = imagecreatefromgif($this->source); break; case 2: $img = imagecreatefromjpeg($this->source); break; case 3: $img = imagecreatefrompng($this->source); break; default: break; } if (!$img) return false; $this->handle = imagecreatetruecolor($this->width, $this->height); imagealphablending($this->handle, false); imagesavealpha($this->handle, true); imagecopyresampled($this->handle, $img, 0, 0, 0, 0, $this->width, $this->height, $this->width, $this->height); return true; } 

(Personally, I prefer ImageMagick over GD).

+2
source

Source: https://habr.com/ru/post/889711/


All Articles