PHP GD使用一个图像来屏蔽另一个图像,包括透明度

时间:2021-11-26 23:16:10

I am trying to create a PHP script that takes an image:

我正在尝试创建一个带有图像的PHP脚本:

PHP GD使用一个图像来屏蔽另一个图像,包括透明度
http://i.stack.imgur.com/eNvlM.png

http://i.stack.imgur.com/eNvlM.png

and then applies a PNG image:

然后应用PNG图像:

PHP GD使用一个图像来屏蔽另一个图像,包括透明度
http://i.stack.imgur.com/iJr2I.png

http://i.stack.imgur.com/iJr2I.png

as a mask.

作为面具。

The end result needs to maintain transparency:

最终结果需要保持透明度:

PHP GD使用一个图像来屏蔽另一个图像,包括透明度
http://i.stack.imgur.com/u0l0I.png

http://i.stack.imgur.com/u0l0I.png

If at all possible I want to do this in GD, ImageMagick is not really an option right now.

如果可能的话我想在GD中这样做,ImageMagick现在不是一个真正的选择。

How would I go about this?

我怎么会这样呢?

phalacee's post (in "PHP/GD, how to copy a circle from one image to another?") seems to be along the right lines but I specifically need to use an image as a mask, not a shape.

phalacee的帖子(在“PHP / GD中,如何将圆圈从一个图像复制到另一个图像?”)似乎沿着正确的线条,但我特别需要使用图像作为遮罩,而不是形状。

6 个解决方案

#1


48  

Matt,

马特,

If you make your png with the oval white fill on black background instead of black fill with transparent background the following function does it.

如果你使用黑色背景上的椭圆形白色填充而不是带有透明背景的黑色填充,则使用以下功能。

<?php
// Load source and mask
$source = imagecreatefrompng( '1.png' );
$mask = imagecreatefrompng( '2.png' );
// Apply mask to source
imagealphamask( $source, $mask );
// Output
header( "Content-type: image/png");
imagepng( $source );

function imagealphamask( &$picture, $mask ) {
    // Get sizes and set up new picture
    $xSize = imagesx( $picture );
    $ySize = imagesy( $picture );
    $newPicture = imagecreatetruecolor( $xSize, $ySize );
    imagesavealpha( $newPicture, true );
    imagefill( $newPicture, 0, 0, imagecolorallocatealpha( $newPicture, 0, 0, 0, 127 ) );

    // Resize mask if necessary
    if( $xSize != imagesx( $mask ) || $ySize != imagesy( $mask ) ) {
        $tempPic = imagecreatetruecolor( $xSize, $ySize );
        imagecopyresampled( $tempPic, $mask, 0, 0, 0, 0, $xSize, $ySize, imagesx( $mask ), imagesy( $mask ) );
        imagedestroy( $mask );
        $mask = $tempPic;
    }

    // Perform pixel-based alpha map application
    for( $x = 0; $x < $xSize; $x++ ) {
        for( $y = 0; $y < $ySize; $y++ ) {
            $alpha = imagecolorsforindex( $mask, imagecolorat( $mask, $x, $y ) );
            $alpha = 127 - floor( $alpha[ 'red' ] / 2 );
            $color = imagecolorsforindex( $picture, imagecolorat( $picture, $x, $y ) );
            imagesetpixel( $newPicture, $x, $y, imagecolorallocatealpha( $newPicture, $color[ 'red' ], $color[ 'green' ], $color[ 'blue' ], $alpha ) );
        }
    }

    // Copy back to original picture
    imagedestroy( $picture );
    $picture = $newPicture;
}

?>

#2


10  

Here's a little upgrade to this script - I found that if the source image has transparency itself, the mask (using the script above) plots a back pixel instead of the source image's transparent pixel. The below extended script takes source image transparency into consideration, and preserves it.

这是对这个脚本的一点升级 - 我发现如果源图像本身具有透明度,则掩码(使用上面的脚本)绘制后像素而不是源图像的透明像素。以下扩展脚本将源图像透明度考虑在内,并保留它。

// Load source and mask
$source = imagecreatefrompng( '1.png' );
$mask = imagecreatefrompng( '2.png' );
// Apply mask to source
imagealphamask( $source, $mask );
// Output
header( "Content-type: image/png");
imagepng( $source );

function imagealphamask( &$picture, $mask ) {
// Get sizes and set up new picture
$xSize = imagesx( $picture );
$ySize = imagesy( $picture );
$newPicture = imagecreatetruecolor( $xSize, $ySize );
imagesavealpha( $newPicture, true );
imagefill( $newPicture, 0, 0, imagecolorallocatealpha( $newPicture, 0, 0, 0, 127 ) );

// Resize mask if necessary
if( $xSize != imagesx( $mask ) || $ySize != imagesy( $mask ) ) {
    $tempPic = imagecreatetruecolor( $xSize, $ySize );
    imagecopyresampled( $tempPic, $mask, 0, 0, 0, 0, $xSize, $ySize, imagesx( $mask ), imagesy( $mask ) );
    imagedestroy( $mask );
    $mask = $tempPic;
}

// Perform pixel-based alpha map application
for( $x = 0; $x < $xSize; $x++ ) {
    for( $y = 0; $y < $ySize; $y++ ) {
        $alpha = imagecolorsforindex( $mask, imagecolorat( $mask, $x, $y ) );

            if(($alpha['red'] == 0) && ($alpha['green'] == 0) && ($alpha['blue'] == 0) && ($alpha['alpha'] == 0))
            {
                // It's a black part of the mask
                imagesetpixel( $newPicture, $x, $y, imagecolorallocatealpha( $newPicture, 0, 0, 0, 127 ) ); // Stick a black, but totally transparent, pixel in.
            }
            else
            {

                // Check the alpha state of the corresponding pixel of the image we're dealing with.    
                $alphaSource = imagecolorsforindex( $source, imagecolorat( $source, $x, $y ) );

                if(($alphaSource['alpha'] == 127))
                {
                    imagesetpixel( $newPicture, $x, $y, imagecolorallocatealpha( $newPicture, 0, 0, 0, 127 ) ); // Stick a black, but totally transparent, pixel in.
                } 
                else
                {
                    $color = imagecolorsforindex( $source, imagecolorat( $source, $x, $y ) );
                    imagesetpixel( $newPicture, $x, $y, imagecolorallocatealpha( $newPicture, $color[ 'red' ], $color[ 'green' ], $color[ 'blue' ], $color['alpha'] ) ); // Stick the pixel from the source image in
                }


            }
    }
}

// Copy back to original picture
imagedestroy( $picture );
$picture = $newPicture;
}

#3


9  

I like your script, good idea to remove extra colour information when the pixel is totally transparent. I should point out just a small error (IMO) though if anyone wants to use this method.

我喜欢你的脚本,当像素完全透明时,最好删除额外的颜色信息。如果有人想使用这种方法,我应该指出一个小错误(IMO)。

$color = imagecolorsforindex( $source, imagecolorat( $source, $x, $y ) );

should be

应该

$color = imagecolorsforindex( $picture, imagecolorat( $picture, $x, $y ) );

also I'm not 100% sure why you're checking rgb values here if the pixel is 100% transparent

如果像素是100%透明的话,我也不是100%肯定你为什么要检查rgb值

if(($alpha['red'] == 0) && ($alpha['green'] == 0) && ($alpha['blue'] == 0) && ($alpha['alpha'] == 0))
...

and I'm not sure alpha blending from the mask file would work well with your method, as its only used when rgba values all equal 0.

而且我不确定掩码文件中的alpha混合是否适用于您的方法,因为它仅在rgba值等于0时使用。

Jules's script is pretty good too, though it expects the mask to be a grey scale representation of a mask (which is pretty common practice).

Jules的剧本也很不错,但它希望蒙版是面具的灰度表示(这是很常见的做法)。

In Matt's query he was after a script that grabs just the alpha transparency from an existing image and applies it to another image. Here's a simple mod of Jules's script just to grab the alpha from the mask image, and preserve the alpha of the source image.

在Matt的询问中,他在一个脚本之后,它只从现有图像中抓取alpha透明度并将其应用于另一个图像。这是Jules脚本的简单模型,只是为了从掩模图像中获取alpha,并保留源图像的alpha。

<?php
// Load source and mask
$source = imagecreatefrompng( '1.png' );
$mask = imagecreatefrompng( '2.png' );
// Apply mask to source
imagealphamask( $source, $mask );
// Output
header( "Content-type: image/png");
imagepng( $source );

function imagealphamask( &$picture, $mask ) {
    // Get sizes and set up new picture
    $xSize = imagesx( $picture );
    $ySize = imagesy( $picture );
    $newPicture = imagecreatetruecolor( $xSize, $ySize );
    imagesavealpha( $newPicture, true );
    imagefill( $newPicture, 0, 0, imagecolorallocatealpha( $newPicture, 0, 0, 0, 127 ) );

    // Resize mask if necessary
    if( $xSize != imagesx( $mask ) || $ySize != imagesy( $mask ) ) {
        $tempPic = imagecreatetruecolor( $xSize, $ySize );
        imagecopyresampled( $tempPic, $mask, 0, 0, 0, 0, $xSize, $ySize, imagesx( $mask ), imagesy( $mask ) );
        imagedestroy( $mask );
        $mask = $tempPic;
    }

    // Perform pixel-based alpha map application
    for( $x = 0; $x < $xSize; $x++ ) {
        for( $y = 0; $y < $ySize; $y++ ) {
            $alpha = imagecolorsforindex( $mask, imagecolorat( $mask, $x, $y ) );
            //small mod to extract alpha, if using a black(transparent) and white
            //mask file instead change the following line back to Jules's original:
            //$alpha = 127 - floor($alpha['red'] / 2);
            //or a white(transparent) and black mask file:
            //$alpha = floor($alpha['red'] / 2);
            $alpha = $alpha['alpha'];
            $color = imagecolorsforindex( $picture, imagecolorat( $picture, $x, $y ) );
            //preserve alpha by comparing the two values
            if ($color['alpha'] > $alpha)
                $alpha = $color['alpha'];
            //kill data for fully transparent pixels
            if ($alpha == 127) {
                $color['red'] = 0;
                $color['blue'] = 0;
                $color['green'] = 0;
            }
            imagesetpixel( $newPicture, $x, $y, imagecolorallocatealpha( $newPicture, $color[ 'red' ], $color[ 'green' ], $color[ 'blue' ], $alpha ) );
        }
    }

    // Copy back to original picture
    imagedestroy( $picture );
    $picture = $newPicture;
}

?>

#4


2  

There's a library called WideImage that supports alpha masks http://wideimage.sourceforge.net/documentation/manipulating-images/

有一个名为WideImage的库,支持alpha掩码http://wideimage.sourceforge.net/documentation/manipulating-images/

#5


1  

for ($y = 0; $y < $ySize; $y++) {
  $alpha = imagecolorsforindex($mask, imagecolorat($mask, $x, $y));
  $alpha = 127 - floor($alpha['red'] / 2);
  if (127 == $alpha) {
    continue;
  }
  $color = imagecolorsforindex($picture, imagecolorat($picture, $x, $y));
  imagesetpixel($newPicture, $x, $y, imagecolorallocatealpha(
    $newPicture, $color['red'], $color['green'], $color['blue'], $alpha));
}

Here is a little upgrade for the first function. As you already have a transparent image, you don't need to copy the masked pixels. This will help the execution a little.

这是第一个功能的一点升级。由于您已有透明图像,因此无需复制蒙版像素。这将有助于执行一点。

#6


0  

A different way to get a similar effect is to paste the png file onto a new image with a unique background colour to temporarily remove transparency, and set the transparent colour of the png image to the black circle colour instead. Then when you place it over the jpeg image, you set the new transparent colour to the colour of the mask.

获得类似效果的另一种方法是将png文件粘贴到具有唯一背景颜色的新图像上以临时删除透明度,并将png图像的透明颜色设置为黑色圆圈颜色。然后,当您将其放在jpeg图像上时,将新的透明颜色设置为蒙版的颜色。

// Load the Black Circle PNG image
$png = imagecreatefrompng( 'mask.png' );
$width = imagesx( $png );
$height = imagesy( $png );

// Create a mask image
$mask = imagecreatetruecolor( $width, $height );
// We'll use Magenta as our new transparent colour - set it as the solid background colour.
$magenta = imagecolorallocate( $mask, 255, 0, 255 );
imagefill( $mask, 0, 0, $magenta );

// Copy the png image onto the mask. Destroy it to free up memory.
imagecopyresampled( $mask, $png, 0, 0, 0, 0, $width, $height, $width, $height );
imagedestroy( $png );

// Set the black portion of the mask to transparent.
$black = imagecolorallocate( $mask, 0, 0, 0 );
imagecolortransparent( $mask, $black );

// Load JPEG image.
$jpg = imagecreatefromjpeg( 'image.jpg' );
$j_width = imagesx( $jpg );
$j_height = imagesx( $jpg );

// Enable alpha blending and copy the png image
imagealphablending( $jpg, true );
imagecopyresampled( $jpg, $mask, 0, 0, 0, 0, $j_width, $j_height, $width, $height );
imagedestroy( $mask );

// Set the new transparent colour and output new image to browser as a png.
$magenta = imagecolorallocate( $jpg, 255, 0, 255 );
imagecolortransparent( $jpg, $magenta );
imagepng( $jpg );

If resampling or semi-transparent pixels are getting you down, instead of using a png as a mask, you can disable blending and draw a transparent shape onto $mask image instead.

如果重新采样或半透明像素让您失望,而不是使用png作为蒙版,则可以禁用混合并在$ mask图像上绘制透明形状。

// Load JPEG Image.
$jpg = imagecreatefromjpeg( 'image.jpg' );
$width = imagesx( $jpg );
$height = imagesx( $jpg );

// Create mask at same size with an opaque background.
$mask = imagecreatetruecolor( $width, $height );
$magenta = imagecolorallocate( $mask, 255, 0, 255 );
imagefill( $mask, 0, 0, $magenta );

// Disable alpha blending and draw a transparent shape onto the mask.
$transparent = imagecolorallocatealpha( $mask, 255, 255, 255, 127 );
imagealphablending( $mask, false );
imagefilledellipse( $mask, round( $width / 2 ), round( $height / 2 ), $width, $height, $transparent );

// Paste the mask onto the original image and set the new transparent colour.
imagealphablending( $jpg, true );
imagecopyresampled( $jpg, $mask, 0, 0, 0, 0, $width, $height, $width, $height );
imagedestroy( $mask );
$magenta = imagecolorallocate( $jpg, 255, 0, 255 );
imagecolortransparent( $jpg, $magenta );

// Output new image to browser as a png.
imagepng( $jpg );

Note: The above code is untested, but should hopefully do what you need it to.

注意:上面的代码未经测试,但应该有希望做到你需要它。

#1


48  

Matt,

马特,

If you make your png with the oval white fill on black background instead of black fill with transparent background the following function does it.

如果你使用黑色背景上的椭圆形白色填充而不是带有透明背景的黑色填充,则使用以下功能。

<?php
// Load source and mask
$source = imagecreatefrompng( '1.png' );
$mask = imagecreatefrompng( '2.png' );
// Apply mask to source
imagealphamask( $source, $mask );
// Output
header( "Content-type: image/png");
imagepng( $source );

function imagealphamask( &$picture, $mask ) {
    // Get sizes and set up new picture
    $xSize = imagesx( $picture );
    $ySize = imagesy( $picture );
    $newPicture = imagecreatetruecolor( $xSize, $ySize );
    imagesavealpha( $newPicture, true );
    imagefill( $newPicture, 0, 0, imagecolorallocatealpha( $newPicture, 0, 0, 0, 127 ) );

    // Resize mask if necessary
    if( $xSize != imagesx( $mask ) || $ySize != imagesy( $mask ) ) {
        $tempPic = imagecreatetruecolor( $xSize, $ySize );
        imagecopyresampled( $tempPic, $mask, 0, 0, 0, 0, $xSize, $ySize, imagesx( $mask ), imagesy( $mask ) );
        imagedestroy( $mask );
        $mask = $tempPic;
    }

    // Perform pixel-based alpha map application
    for( $x = 0; $x < $xSize; $x++ ) {
        for( $y = 0; $y < $ySize; $y++ ) {
            $alpha = imagecolorsforindex( $mask, imagecolorat( $mask, $x, $y ) );
            $alpha = 127 - floor( $alpha[ 'red' ] / 2 );
            $color = imagecolorsforindex( $picture, imagecolorat( $picture, $x, $y ) );
            imagesetpixel( $newPicture, $x, $y, imagecolorallocatealpha( $newPicture, $color[ 'red' ], $color[ 'green' ], $color[ 'blue' ], $alpha ) );
        }
    }

    // Copy back to original picture
    imagedestroy( $picture );
    $picture = $newPicture;
}

?>

#2


10  

Here's a little upgrade to this script - I found that if the source image has transparency itself, the mask (using the script above) plots a back pixel instead of the source image's transparent pixel. The below extended script takes source image transparency into consideration, and preserves it.

这是对这个脚本的一点升级 - 我发现如果源图像本身具有透明度,则掩码(使用上面的脚本)绘制后像素而不是源图像的透明像素。以下扩展脚本将源图像透明度考虑在内,并保留它。

// Load source and mask
$source = imagecreatefrompng( '1.png' );
$mask = imagecreatefrompng( '2.png' );
// Apply mask to source
imagealphamask( $source, $mask );
// Output
header( "Content-type: image/png");
imagepng( $source );

function imagealphamask( &$picture, $mask ) {
// Get sizes and set up new picture
$xSize = imagesx( $picture );
$ySize = imagesy( $picture );
$newPicture = imagecreatetruecolor( $xSize, $ySize );
imagesavealpha( $newPicture, true );
imagefill( $newPicture, 0, 0, imagecolorallocatealpha( $newPicture, 0, 0, 0, 127 ) );

// Resize mask if necessary
if( $xSize != imagesx( $mask ) || $ySize != imagesy( $mask ) ) {
    $tempPic = imagecreatetruecolor( $xSize, $ySize );
    imagecopyresampled( $tempPic, $mask, 0, 0, 0, 0, $xSize, $ySize, imagesx( $mask ), imagesy( $mask ) );
    imagedestroy( $mask );
    $mask = $tempPic;
}

// Perform pixel-based alpha map application
for( $x = 0; $x < $xSize; $x++ ) {
    for( $y = 0; $y < $ySize; $y++ ) {
        $alpha = imagecolorsforindex( $mask, imagecolorat( $mask, $x, $y ) );

            if(($alpha['red'] == 0) && ($alpha['green'] == 0) && ($alpha['blue'] == 0) && ($alpha['alpha'] == 0))
            {
                // It's a black part of the mask
                imagesetpixel( $newPicture, $x, $y, imagecolorallocatealpha( $newPicture, 0, 0, 0, 127 ) ); // Stick a black, but totally transparent, pixel in.
            }
            else
            {

                // Check the alpha state of the corresponding pixel of the image we're dealing with.    
                $alphaSource = imagecolorsforindex( $source, imagecolorat( $source, $x, $y ) );

                if(($alphaSource['alpha'] == 127))
                {
                    imagesetpixel( $newPicture, $x, $y, imagecolorallocatealpha( $newPicture, 0, 0, 0, 127 ) ); // Stick a black, but totally transparent, pixel in.
                } 
                else
                {
                    $color = imagecolorsforindex( $source, imagecolorat( $source, $x, $y ) );
                    imagesetpixel( $newPicture, $x, $y, imagecolorallocatealpha( $newPicture, $color[ 'red' ], $color[ 'green' ], $color[ 'blue' ], $color['alpha'] ) ); // Stick the pixel from the source image in
                }


            }
    }
}

// Copy back to original picture
imagedestroy( $picture );
$picture = $newPicture;
}

#3


9  

I like your script, good idea to remove extra colour information when the pixel is totally transparent. I should point out just a small error (IMO) though if anyone wants to use this method.

我喜欢你的脚本,当像素完全透明时,最好删除额外的颜色信息。如果有人想使用这种方法,我应该指出一个小错误(IMO)。

$color = imagecolorsforindex( $source, imagecolorat( $source, $x, $y ) );

should be

应该

$color = imagecolorsforindex( $picture, imagecolorat( $picture, $x, $y ) );

also I'm not 100% sure why you're checking rgb values here if the pixel is 100% transparent

如果像素是100%透明的话,我也不是100%肯定你为什么要检查rgb值

if(($alpha['red'] == 0) && ($alpha['green'] == 0) && ($alpha['blue'] == 0) && ($alpha['alpha'] == 0))
...

and I'm not sure alpha blending from the mask file would work well with your method, as its only used when rgba values all equal 0.

而且我不确定掩码文件中的alpha混合是否适用于您的方法,因为它仅在rgba值等于0时使用。

Jules's script is pretty good too, though it expects the mask to be a grey scale representation of a mask (which is pretty common practice).

Jules的剧本也很不错,但它希望蒙版是面具的灰度表示(这是很常见的做法)。

In Matt's query he was after a script that grabs just the alpha transparency from an existing image and applies it to another image. Here's a simple mod of Jules's script just to grab the alpha from the mask image, and preserve the alpha of the source image.

在Matt的询问中,他在一个脚本之后,它只从现有图像中抓取alpha透明度并将其应用于另一个图像。这是Jules脚本的简单模型,只是为了从掩模图像中获取alpha,并保留源图像的alpha。

<?php
// Load source and mask
$source = imagecreatefrompng( '1.png' );
$mask = imagecreatefrompng( '2.png' );
// Apply mask to source
imagealphamask( $source, $mask );
// Output
header( "Content-type: image/png");
imagepng( $source );

function imagealphamask( &$picture, $mask ) {
    // Get sizes and set up new picture
    $xSize = imagesx( $picture );
    $ySize = imagesy( $picture );
    $newPicture = imagecreatetruecolor( $xSize, $ySize );
    imagesavealpha( $newPicture, true );
    imagefill( $newPicture, 0, 0, imagecolorallocatealpha( $newPicture, 0, 0, 0, 127 ) );

    // Resize mask if necessary
    if( $xSize != imagesx( $mask ) || $ySize != imagesy( $mask ) ) {
        $tempPic = imagecreatetruecolor( $xSize, $ySize );
        imagecopyresampled( $tempPic, $mask, 0, 0, 0, 0, $xSize, $ySize, imagesx( $mask ), imagesy( $mask ) );
        imagedestroy( $mask );
        $mask = $tempPic;
    }

    // Perform pixel-based alpha map application
    for( $x = 0; $x < $xSize; $x++ ) {
        for( $y = 0; $y < $ySize; $y++ ) {
            $alpha = imagecolorsforindex( $mask, imagecolorat( $mask, $x, $y ) );
            //small mod to extract alpha, if using a black(transparent) and white
            //mask file instead change the following line back to Jules's original:
            //$alpha = 127 - floor($alpha['red'] / 2);
            //or a white(transparent) and black mask file:
            //$alpha = floor($alpha['red'] / 2);
            $alpha = $alpha['alpha'];
            $color = imagecolorsforindex( $picture, imagecolorat( $picture, $x, $y ) );
            //preserve alpha by comparing the two values
            if ($color['alpha'] > $alpha)
                $alpha = $color['alpha'];
            //kill data for fully transparent pixels
            if ($alpha == 127) {
                $color['red'] = 0;
                $color['blue'] = 0;
                $color['green'] = 0;
            }
            imagesetpixel( $newPicture, $x, $y, imagecolorallocatealpha( $newPicture, $color[ 'red' ], $color[ 'green' ], $color[ 'blue' ], $alpha ) );
        }
    }

    // Copy back to original picture
    imagedestroy( $picture );
    $picture = $newPicture;
}

?>

#4


2  

There's a library called WideImage that supports alpha masks http://wideimage.sourceforge.net/documentation/manipulating-images/

有一个名为WideImage的库,支持alpha掩码http://wideimage.sourceforge.net/documentation/manipulating-images/

#5


1  

for ($y = 0; $y < $ySize; $y++) {
  $alpha = imagecolorsforindex($mask, imagecolorat($mask, $x, $y));
  $alpha = 127 - floor($alpha['red'] / 2);
  if (127 == $alpha) {
    continue;
  }
  $color = imagecolorsforindex($picture, imagecolorat($picture, $x, $y));
  imagesetpixel($newPicture, $x, $y, imagecolorallocatealpha(
    $newPicture, $color['red'], $color['green'], $color['blue'], $alpha));
}

Here is a little upgrade for the first function. As you already have a transparent image, you don't need to copy the masked pixels. This will help the execution a little.

这是第一个功能的一点升级。由于您已有透明图像,因此无需复制蒙版像素。这将有助于执行一点。

#6


0  

A different way to get a similar effect is to paste the png file onto a new image with a unique background colour to temporarily remove transparency, and set the transparent colour of the png image to the black circle colour instead. Then when you place it over the jpeg image, you set the new transparent colour to the colour of the mask.

获得类似效果的另一种方法是将png文件粘贴到具有唯一背景颜色的新图像上以临时删除透明度,并将png图像的透明颜色设置为黑色圆圈颜色。然后,当您将其放在jpeg图像上时,将新的透明颜色设置为蒙版的颜色。

// Load the Black Circle PNG image
$png = imagecreatefrompng( 'mask.png' );
$width = imagesx( $png );
$height = imagesy( $png );

// Create a mask image
$mask = imagecreatetruecolor( $width, $height );
// We'll use Magenta as our new transparent colour - set it as the solid background colour.
$magenta = imagecolorallocate( $mask, 255, 0, 255 );
imagefill( $mask, 0, 0, $magenta );

// Copy the png image onto the mask. Destroy it to free up memory.
imagecopyresampled( $mask, $png, 0, 0, 0, 0, $width, $height, $width, $height );
imagedestroy( $png );

// Set the black portion of the mask to transparent.
$black = imagecolorallocate( $mask, 0, 0, 0 );
imagecolortransparent( $mask, $black );

// Load JPEG image.
$jpg = imagecreatefromjpeg( 'image.jpg' );
$j_width = imagesx( $jpg );
$j_height = imagesx( $jpg );

// Enable alpha blending and copy the png image
imagealphablending( $jpg, true );
imagecopyresampled( $jpg, $mask, 0, 0, 0, 0, $j_width, $j_height, $width, $height );
imagedestroy( $mask );

// Set the new transparent colour and output new image to browser as a png.
$magenta = imagecolorallocate( $jpg, 255, 0, 255 );
imagecolortransparent( $jpg, $magenta );
imagepng( $jpg );

If resampling or semi-transparent pixels are getting you down, instead of using a png as a mask, you can disable blending and draw a transparent shape onto $mask image instead.

如果重新采样或半透明像素让您失望,而不是使用png作为蒙版,则可以禁用混合并在$ mask图像上绘制透明形状。

// Load JPEG Image.
$jpg = imagecreatefromjpeg( 'image.jpg' );
$width = imagesx( $jpg );
$height = imagesx( $jpg );

// Create mask at same size with an opaque background.
$mask = imagecreatetruecolor( $width, $height );
$magenta = imagecolorallocate( $mask, 255, 0, 255 );
imagefill( $mask, 0, 0, $magenta );

// Disable alpha blending and draw a transparent shape onto the mask.
$transparent = imagecolorallocatealpha( $mask, 255, 255, 255, 127 );
imagealphablending( $mask, false );
imagefilledellipse( $mask, round( $width / 2 ), round( $height / 2 ), $width, $height, $transparent );

// Paste the mask onto the original image and set the new transparent colour.
imagealphablending( $jpg, true );
imagecopyresampled( $jpg, $mask, 0, 0, 0, 0, $width, $height, $width, $height );
imagedestroy( $mask );
$magenta = imagecolorallocate( $jpg, 255, 0, 255 );
imagecolortransparent( $jpg, $magenta );

// Output new image to browser as a png.
imagepng( $jpg );

Note: The above code is untested, but should hopefully do what you need it to.

注意:上面的代码未经测试,但应该有希望做到你需要它。