如何使用 PHP GD 库将多个不同大小的透明 png 合并为一个图像而不进行裁剪?

How to merge multiple transparent pngs with different size into one image without cropping, using PHP GD library?

我想将多个具有透明背景的 png 合并为一个图像。图像具有不同的大小,因此,当图像彼此重叠放置时,只有在最上面图像的大小范围内才会显示合并图像的部分。

这就像最后一张图像像蒙版一样应用于之前合并的图像。我希望看到所有图像都与它们的原始大小合并,而不裁剪超出最后一张图像大小的部分。

这是我目前使用的代码:

$images = array();
    foreach (scandir($this->img_dir) as $key => $dirname) {
        if(!strstr($dirname, "."))
        {
            if(isset($_GET[$dirname])) 
            {
                foreach ($this->layer_order as $lkey => $order) {
                    if($lkey == $dirname)
                        $images[$order] = glob($this->img_dir . "/" . $dirname . "/" . $_GET[$dirname] . ".png");
                }
            }
        }
    }


    $destination = imagecreatetruecolor(458, 600);


    imagealphablending($destination, true);
    imagesavealpha($destination, true);

    ksort($images);
    foreach($images as $key => $value) {        
        foreach ($value as $fn) {
            // Load image
            $source = imagecreatefrompng($fn);
            //$source = $this->resize_image($source, 50, 50, 2);

            // Copy over image
            imagecopy($destination, $source, 10, 50, 0, 0, 458, 600);

            // Free memory
            imagedestroy($source);
        }
    }

    return $destination;

我不知道这是否是我尝试实现的最佳解决方案,但经过几次尝试和一些研究后,我使用了一种相当简单的方法来避免合并队列中的最后一张图像,屏蔽其他图像它的尺寸相对较小。这样,每张图像都将根据用户的需要进行合并和定位,在指定的 canvas 大小内,并具有透明度。

我 post 功能的全部内容,以防有人需要类似的解决方案。这是 class.

中的一个函数
    $images = array();

    // Foreach loop to set images order and creating an array with image paths using params from $_GET before merging
    foreach (scandir($this->img_dir) as $key => $dirname) {
        if(!strstr($dirname, "."))
        {
            if(isset($_GET[$dirname])) 
            {
                foreach ($this->layer_order as $lkey => $order) {
                    if($lkey == $dirname) {
                        $imageArray = glob($this->img_dir . "/" . $dirname . "/" . ($dirname == "door" && isset($_GET['type']) ? $_GET['type']."/" : "") . $_GET[$dirname] . ".png");
                        foreach ($imageArray as $imgPath) {
                            $images[$order] = $imgPath;
                        }
                    }       
                }
            }
        }
    }

    // Allocate new image
    $destination = imagecreatetruecolor($this->canvas_width, $this->canvas_height);

    imagealphablending($destination, false);
    $col = imagecolorallocatealpha($destination, 255, 255, 255, 127);
    imagefilledrectangle($destination, 0, 0, $this->canvas_width, $this->canvas_height, $col);
    imagealphablending($destination, true);

    // Sort order
    ksort($images);

    // Merging images
    foreach($images as $key => $fn) {

        // Load image
        if(strstr($fn, "handle")) 
        {
            $source = $this->resizePng($fn, 0.18, 100, 205);
            imagecopy($destination, $source, 0, 0, 0, 0, $this->canvas_width, $this->canvas_height);
        }
        elseif (strstr($fn, "glass")) 
        {
            // Create a background image by filling a canvas with small image tiles. Params: $file, $shrink_ratio_percent, $column_size, $stretch
            $source = $this->multiplyMergeAndResizePngs($fn, 0.2095, 3, 3.6);
            // Applying mask on images based on black and white patterns
            if ($this->glass_mask)
                $source = $this->createMask($source, $this->glass_mask);
            imagecopy($destination, $source, 118, 28, 0, 0, $this->canvas_width, $this->canvas_height);
        }
        elseif (strstr($fn, "door")) 
        {    
            $source = imagecreatefrompng($fn);
            imagecopy($destination, $source, 32, 0, 0, 0, $this->canvas_width, $this->canvas_height);
        } else {
            $source = imagecreatefrompng($fn);
            imagecopy($destination, $source, 0, 0, 0, 0, $this->canvas_width, $this->canvas_height);
        }

        imagealphablending($destination, true);

        // Free memory
        imagedestroy($source);
    }

    return $destination;