开发者

PHP & GD - transparent background being filled with nearby color

I know PHP+GD Transparency issues have been beat to death on this and many other sites, but I've followed all the recommendations and I can't seem to fix my issue.

First, the explanation:

I am trying to overlay one image on top of another on开发者_如何学JAVAe. They both have areas that are transparent. As a demo that I know should look a particular way, I am trying to overlay a checkmark on top of a blue arrow shape that I created.

Here are the two images:

PHP & GD - transparent background being filled with nearby color

PHP & GD - transparent background being filled with nearby color

Now to my code:

I am using a library/API that I built to take a TINY bit of the pain away from editing images with PHP+GD. It's still in it's infancy, but the pertinent files are:

The Base Class

The Main Loader

The (poorly named) Combine Class

I am running 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 output to be something like this:

PHP & GD - transparent background being filled with nearby color

But instead I get this:

PHP & GD - transparent background being filled with nearby color

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

In the Combine Class I linked above, I have also tried imagecopy, imagecopyresampled, and the vanilla imagecopymerge, both with similar results.

I'm at a total loss.

Edit:

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

Update:

Please note, when a new Image object is created, it calls newImage which contains the following code:

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

I feel like that might be easy to miss.


Note that it doesn't matter that you create the handle in newImage and call imagealphablending and imagesavealpha on it, because loadImage throws that handle away.

The reason it is "filling" the transparent area with the blue color is that it is not filling the transparent area with anything at all. It it just completely dropping the alpha channel, and the blue color is what happens to be stored in those pixels with an alpha of zero. Note this may be difficult to see in a graphics program, as that program may itself replace completely-transparent pixels with black or white.

As for what is wrong with your code, I can't say for sure as I don't get the same results as you report when I try your existing code. But if I change your loadImage to something like this so the source images are forced to true color, it 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).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜