以下PHP代码段使用GD将浏览器上传的PNG大小调整为128x128。它的效果很好,除了原始图像中的透明区域在我的情况下被替换为纯黑色。
即使设置了imagesavealpha
,也有些不对。
保留重采样图像透明度的最佳方法是什么?
$uploadTempFile = $myField[ 'tmp_name' ]
list( $uploadWidth, $uploadHeight, $uploadType )
= getimagesize( $uploadTempFile );
$srcImage = imagecreatefrompng( $uploadTempFile );
imagesavealpha( $targetImage, true );
$targetImage = imagecreatetruecolor( 128, 128 );
imagecopyresampled( $targetImage, $srcImage,
0, 0,
0, 0,
128, 128,
$uploadWidth, $uploadHeight );
imagepng( $targetImage, 'out.png', 9 );
答案 0 :(得分:189)
imagealphablending( $targetImage, false );
imagesavealpha( $targetImage, true );
为我做了。谢谢ceejayoz。
请注意,目标图像需要Alpha设置,而不是源图像。
编辑: 完整的替代码。另见以下答案及其评论。这不能保证在任何方面都是完美的,但在当时确实满足了我的需求。
$uploadTempFile = $myField[ 'tmp_name' ]
list( $uploadWidth, $uploadHeight, $uploadType )
= getimagesize( $uploadTempFile );
$srcImage = imagecreatefrompng( $uploadTempFile );
$targetImage = imagecreatetruecolor( 128, 128 );
imagealphablending( $targetImage, false );
imagesavealpha( $targetImage, true );
imagecopyresampled( $targetImage, $srcImage,
0, 0,
0, 0,
128, 128,
$uploadWidth, $uploadHeight );
imagepng( $targetImage, 'out.png', 9 );
答案 1 :(得分:21)
为什么你这么复杂?以下是我使用的内容,到目前为止它已经完成了我的工作。
$im = ImageCreateFromPNG($source);
$new_im = imagecreatetruecolor($new_size[0],$new_size[1]);
imagecolortransparent($new_im, imagecolorallocate($new_im, 0, 0, 0));
imagecopyresampled($new_im,$im,0,0,0,0,$new_size[0],$new_size[1],$size[0],$size[1]);
答案 2 :(得分:10)
我相信这应该可以解决问题:
$srcImage = imagecreatefrompng($uploadTempFile);
imagealphablending($srcImage, false);
imagesavealpha($srcImage, true);
编辑: PHP文档声明imagealphablending
中的某些人应该是真的,而不是假的。 YMMV。
答案 3 :(得分:9)
答案 4 :(得分:6)
我已经制作了一个功能,可以使用copyimageresample
调整JPEG / GIF / PNG图像的大小,并且PNG图像仍保持透明度:
$myfile=$_FILES["youimage"];
function ismyimage($myfile) {
if((($myfile["type"] == "image/gif") || ($myfile["type"] == "image/jpg") || ($myfile["type"] == "image/jpeg") || ($myfile["type"] == "image/png")) && ($myfile["size"] <= 2097152 /*2mb*/) ) return true;
else return false;
}
function upload_file($myfile) {
if(ismyimage($myfile)) {
$information=getimagesize($myfile["tmp_name"]);
$mywidth=$information[0];
$myheight=$information[1];
$newwidth=$mywidth;
$newheight=$myheight;
while(($newwidth > 600) || ($newheight > 400 )) {
$newwidth = $newwidth-ceil($newwidth/100);
$newheight = $newheight-ceil($newheight/100);
}
$files=$myfile["name"];
if($myfile["type"] == "image/gif") {
$tmp=imagecreatetruecolor($newwidth,$newheight);
$src=imagecreatefromgif($myfile["tmp_name"]);
imagecopyresampled($tmp, $src, 0, 0, 0, 0, $newwidth, $newheight, $mywidth, $myheight);
$con=imagegif($tmp, $files);
imagedestroy($tmp);
imagedestroy($src);
if($con){
return true;
} else {
return false;
}
} else if(($myfile["type"] == "image/jpg") || ($myfile["type"] == "image/jpeg") ) {
$tmp=imagecreatetruecolor($newwidth,$newheight);
$src=imagecreatefromjpeg($myfile["tmp_name"]);
imagecopyresampled($tmp, $src, 0, 0, 0, 0, $newwidth, $newheight, $mywidth, $myheight);
$con=imagejpeg($tmp, $files);
imagedestroy($tmp);
imagedestroy($src);
if($con) {
return true;
} else {
return false;
}
} else if($myfile["type"] == "image/png") {
$tmp=imagecreatetruecolor($newwidth,$newheight);
$src=imagecreatefrompng($myfile["tmp_name"]);
imagealphablending($tmp, false);
imagesavealpha($tmp,true);
$transparent = imagecolorallocatealpha($tmp, 255, 255, 255, 127);
imagefilledrectangle($tmp, 0, 0, $newwidth, $newheight, $transparent);
imagecopyresampled($tmp, $src, 0, 0, 0, 0, $newwidth, $newheight, $mywidth, $myheight);
$con=imagepng($tmp, $files);
imagedestroy($tmp);
imagedestroy($src);
if($con) {
return true;
} else {
return false;
}
}
} else
return false;
}
答案 5 :(得分:4)
我认为这可能会解决问题:
$uploadTempFile = $myField[ 'tmp_name' ]
list( $uploadWidth, $uploadHeight, $uploadType )
= getimagesize( $uploadTempFile );
$srcImage = imagecreatefrompng( $uploadTempFile );
$targetImage = imagecreatetruecolor( 128, 128 );
$transparent = imagecolorallocate($targetImage,0,255,0);
imagecolortransparent($targetImage,$transparent);
imagefilledrectangle($targetImage,0,0,127,127,$transparent);
imagecopyresampled( $targetImage, $srcImage,
0, 0,
0, 0,
128, 128,
$uploadWidth, $uploadHeight );
imagepng( $targetImage, 'out.png', 9 );
缺点是图像将被剥离每100%绿色像素。无论如何,希望它有所帮助:)
答案 6 :(得分:2)
重新设置保留透明度,然后像其他帖子中所述,yesavealpha()必须设置为true,使用alpha标志imagealphablending()必须设置为false,否则它不起作用。
我还在你的代码中发现了两件小事:
getimagesize()
获取imagecopyresmapled()
$uploadWidth
和$uploadHeight
值应为-1
,因为坐标始于0
而不是1
,因此它会将它们复制到空像素。用imagesx($targetImage) - 1
和imagesy($targetImage) - 1
取代它,相对应该应该:)答案 7 :(得分:0)
这是我的总测试代码。它对我有用
$imageFileType = pathinfo($_FILES["image"]["name"], PATHINFO_EXTENSION);
$filename = 'test.' . $imageFileType;
move_uploaded_file($_FILES["image"]["tmp_name"], $filename);
$source_image = imagecreatefromjpeg($filename);
$source_imagex = imagesx($source_image);
$source_imagey = imagesy($source_image);
$dest_imagex = 400;
$dest_imagey = 600;
$dest_image = imagecreatetruecolor($dest_imagex, $dest_imagey);
imagecopyresampled($dest_image, $source_image, 0, 0, 0, 0, $dest_imagex, $dest_imagey, $source_imagex, $source_imagey);
imagesavealpha($dest_image, true);
$trans_colour = imagecolorallocatealpha($dest_image, 0, 0, 0, 127);
imagefill($dest_image, 0, 0, $trans_colour);
imagepng($dest_image,"test1.png",1);
答案 8 :(得分:0)
注意传递给width
函数的源图像的height
和imagecopyresampled
值。如果它们大于实际源图像大小,则其余图像区域将填充黑色。
答案 9 :(得分:0)
我结合了ceejayoz和Cheekysoft的回答,这对我来说是最好的结果。如果没有imagealphablending()和imagesavealpha(),图像将不清晰:
$img3 = imagecreatetruecolor(128, 128);
imagecolortransparent($img3, imagecolorallocate($img3, 0, 0, 0));
imagealphablending( $img3, false );
imagesavealpha( $img3, true );
imagecopyresampled($img3, $srcImage, 0, 0, 0, 0, 128, 128, $uploadWidth, $uploadHeight);
imagepng($img3, 'filename.png', 9);