0

请看这个问题:PHP GD Use one image to mask another image, including contrast to the rules around here say for users to create new questions rather than revisited old questions and ask for support

我一直在使用这个脚本来启用透明遮罩 - (可能的)区别是源图像具有透明度,但似乎下面的代码仅在输入 PNG 没有透明度时才有效。有人可以看看我是否做错了什么?

我在下面尝试做的事情: 1. 抓取一个 $source 图像 2. 调整它的大小并将其保存为 pjg.png,保持透明度(这工作正常) 3. 用另一个 PNG 掩盖结果图像。

信息:

  • image.png 具有透明度。
  • mask1.png 是黑色背景上的白色椭圆,没有透明度
  • 最后保存的图像上有黑色,此时它应该始终保持透明度。

    <?php
    $data       = file_get_contents('assets/img/image.png');
    $source     = imagecreatefromstring( $data);
    
    
    // Set the percentage resize
    
    $percent = 0.5;
    
    // Get new dimensions
    list($width, $height) = getimagesize('assets/img/image.png');
    $new_width = $width * $percent;
    $new_height = $height * $percent;
    
    $image_p = imagecreatetruecolor($new_width, $new_height);
    imagealphablending($image_p, false);
    imagesavealpha( $image_p, true );
    
    imagecopyresampled($image_p, $source, 0, 0, 0, 0, $new_width, $new_height, $width, $height);
    
    imagepng($image_p, "assets/img/pjg.png");
    
    $mask_id = 1;
    
    
    create_mask( $image_p, $mask_id ); 
    
    
    function create_mask( &$picture, $mask_id) {
    // Image masking using PHP
    // https://stackoverflow.com/questions/7203160/php-gd-use-one-image-to-mask-another-image-including-transparency
    
    $mask = imagecreatefrompng( 'assets/img/masks/mask'.$mask_id.'.png' );   // The mask is a white-on-black png
    
    
    
    // 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 ) );
        }
    }
    
    $salt = random_string('alnum', 8); // Another function generating a string, not important
    $now = time();
    $new_filename = $now."_".$salt .".png";
    
    // Save it Locally using a unique name
    imagepng($newPicture, "assets/img/uploads/cropped/".$new_filename);
    
    
    // Copy back to original picture
    imagedestroy( $picture );
    $picture = $newPicture;
    
    }
    

如果有人能指出为什么输出图像没有保持其透明度,那么它会为您提供一杯不错的冰镇啤酒。

谢谢!

PJG

4

1 回答 1

1

我已经解决了。原始脚本没有检查源图像的透明度。下面的脚本检查源图像的像素透明度,并采取相应措施。以下脚本在 PNG 图像上执行 shap 遮罩,并保持源图像的透明度。

<?php
$data       = file_get_contents('assets/img/image.png');
$source     = imagecreatefromstring( $data);


// Set the percentage resize

$percent = 0.5;

// Get new dimensions
list($width, $height) = getimagesize('assets/img/image.png');
$new_width = $width * $percent;
$new_height = $height * $percent;

$image_p = imagecreatetruecolor($new_width, $new_height);
imagealphablending($image_p, false);
imagesavealpha( $image_p, true );

imagecopyresampled($image_p, $source, 0, 0, 0, 0, $new_width, $new_height, $width, $height);

imagepng($image_p, "assets/img/pjg.png");

$mask_id = 1;


create_mask( $image_p, $mask_id ); 


function create_mask( &$picture, $mask_id) {
// Image masking using PHP
// http://stackoverflow.com/questions/7203160/php-gd-use-one-image-to-mask-another-image-including-transparency

$mask = imagecreatefrompng( 'assets/img/masks/mask'.$mask_id.'.png' );   // The mask is a white-on-black png



// 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( $picture, imagecolorat( $picture, $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( $picture, imagecolorat( $picture, $x, $y ) );
                    imagesetpixel( $newPicture, $x, $y, imagecolorallocatealpha( $newPicture, $color[ 'red' ], $color[ 'green' ], $color[ 'blue' ], $color['alpha'] ) ); // Stick the pixel from the source image in
                }


            }
    }
}

$salt = random_string('alnum', 8); // Another function generating a string, not important
$now = time();
$new_filename = $now."_".$salt .".png";

// Save it Locally using a unique name
imagepng($newPicture, "assets/img/uploads/cropped/".$new_filename);


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

}
?>

为阅读干杯——看来我以后要给自己买杯啤酒了:)

PG

于 2012-06-08T02:37:06.823 回答