0

この質問を参照してください: PHP GD Use one image to mask another image, including transparent - このあたりのルールでは、ユーザーは古い質問に戻ってサポートを求めるのではなく、新しい質問を作成するように規定されています。

私はこのスクリプトを使用して透過マスキングを有効にしました - (可能な) 違いはソース画像に透過性があることですが、以下のコードは入力 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 画像にシェイプ マスクを適用し、ソース画像の透明度を維持します。

<?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 に答える