请看这个问题: PHP GD 使用一个图像遮罩另一个图像,包括透明度 - 这里的规则说用户创建新问题,而不是重新访问旧问题并寻求支持
我一直在使用这个脚本来启用透明遮罩 - (可能的)区别在于源图像具有透明度,但似乎下面的代码仅在输入 PNG 没有透明度时才有效。有人可以看看我是否做错了什么吗?
我在下面尝试做什么:1. 抓取$source图像2.调整大小并将其本地保存为pjg.png,保持透明度(这工作正常)3. 用另一个 PNG 遮罩生成的图像。
信息:
- 图像.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
我已经解决了。原始脚本未检查源图像的透明度。下面的脚本检查源图像的像素透明度,并采取相应的措施。下面的脚本在 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;
}
?>
为阅读干杯 - 看起来我稍后会给自己买啤酒:)
噗嗤