简体   繁体   English

PHP & GD - 用附近颜色填充的透明背景

[英]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.我知道 PHP+GD 透明度问题在这个网站和许多其他网站上已经被打死了,但我已经遵循了所有建议,但我似乎无法解决我的问题。

First, the explanation:一、解释:

I am trying to overlay one image on top of another one.我正在尝试将一张图像叠加在另一张图像之上。 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:这是两张图片:

复选标记

蓝色箭头

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.我正在使用我构建的库/API,以减轻使用 PHP+GD 编辑图像的痛苦。 It's still in it's infancy, but the pertinent files are:它仍处于起步阶段,但相关文件是:

The Base Class 底座 Class
The Main Loader主装载机
The (poorly named) Combine Class (名字不好)结合 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:我希望 output 是这样的:

组合图像

But instead I get this:但相反,我得到了这个:

方底

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.在上面链接的组合 Class 中,我还尝试了imagecopyimagecopyresampled和 vanilla imagecopymerge ,两者的结果相似。

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:请注意,当创建一个新的图像 object 时,它会调用包含以下代码的newImage

$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.请注意,在newImage中创建句柄并在其上调用imagealphablendingimagesavealpha重要,因为loadImage会丢弃该句柄。

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.它只是完全放弃了 alpha 通道,而蓝色恰好存储在那些 alpha 为零的像素中。 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:但是,如果我将您的loadImage更改为这样的东西,以便源图像被强制为真彩色,它对我有用:

            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). (就个人而言,我更喜欢 ImageMagick 而不是 GD)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM