如何使用 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;
我想将多个具有透明背景的 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;