我想将多个具有透明背景的 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;
我不知道这是否是我试图实现的最佳解决方案,但经过几次尝试和一些研究,我使用了一种相当简单的方法来避免合并队列中的最后一个图像,用相对较小的尺寸屏蔽其他图像。这样,每个图像都将在指定的画布大小内根据用户想要的清晰度进行合并和定位。
我发布了该功能的全部内容,以防有人需要类似的解决方案。这是类中的一个函数。
$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;