gpt4 book ai didi

php - 使用 imagecopyresampled() PHP GD 圆角透明_平滑_角

转载 作者:可可西里 更新时间:2023-10-31 22:08:40 25 4
gpt4 key购买 nike

我需要一个脚本,它可以在提供的图像上制作圆角透明角。我找到了一个,除了一件事外效果很好:应用的角看起来不光滑。 imageantialias()PHP is running on Debian 后抛出 fatal error 并重新编译它不是一种选择。

我发现使这些角看起来平滑的技巧是使用 imagecopyresampled() 调整图像大小。如下所示:

  1. 准备图片;
  2. imagecopyresample 到 10 倍大小;
  3. 用特殊颜色画角;
  4. 使该颜色透明;
  5. 将图片缩小到原来的大小

但问题来了:结果图像的角(在第 5 步之后)是 smooth, but not transparent .在第 4 步之后发送以输出图像时(即在减小其大小之前)– everything's as it should be .

下面是负责使角变圆的代码部分:

    //    $dest = image resource        $q=10;        // making everything 10x bigger        $new_width=$width*$q;        $new_height=$height*$q;        $radius=$radius*$q;        $magnified=imagecreatetruecolor($new_width, $new_height);        imagecopyresampled($magnified, $dest, 0,0, 0,0, $new_width,$new_height, ($new_width/$q),($new_height/$q));        // picking the unique colour        $found = false;        while($found == false) {            $r = rand(0, 255);            $g = rand(0, 255);            $b = rand(0, 255);            if(imagecolorexact($magnified, $r, $g, $b) != (-1)) {                $found = true;            }        }        $colorcode = imagecolorallocate($magnified, $r, $g, $b);            // drawing corners            imagearc($magnified, $radius-1, $radius-1, $radius*2, $radius*2, 180, 270, $colorcode);            imagefilltoborder($magnified, 0, 0, $colorcode, $colorcode);            imagearc($magnified, $new_width-$radius, $radius-1, $radius*2, $radius*2, 270, 0, $colorcode);            imagefilltoborder($magnified, $new_width-1, 0, $colorcode, $colorcode);            imagearc($magnified, $radius-1, $new_height-$radius, $radius*2, $radius*2, 90, 180, $colorcode);            imagefilltoborder($magnified, 0, $new_height-1, $colorcode, $colorcode);            imagearc($magnified, $new_width-$radius, $new_height-$radius, $radius*2, $radius*2, 0, 90, $colorcode);            imagefilltoborder($magnified, $new_width-1, $new_height-1, $colorcode, $colorcode);        // making the unique colour transparent        imagecolortransparent($magnified, $colorcode);        // scaling down the enlarged image to it's original size        // expecting corners to remain transparent        imagecopyresampled($dest, $magnified, 0,0, 0,0, ($new_width/$q),($new_height/$q), $new_width,$new_height);        // but they're not        // sending $magnified to output for testing purposes        $dest=$magnified;    //    outputting $dest as image/png

如您所见,当放大的图像被图像复制重新采样到其原始大小时,就会出现问题。透明角填充了 $colorcode 颜色。我一直在玩 imagesavealpha()imagealphablending()作为advised , 但没有结果。

请帮助我完成这项工作。

附言这可能有用:上传时 large PNG到 imgur.com 它有它 converted to JPG正如您所看到的,所有角落都充满了经过修复的 $colorcode。

附言希望我不会因为过度使用“扩大”这个词而被禁止:)

最佳答案

经过几个小时的测试并将我的头撞到墙上,我想我找到了解决方案。问题是关于使用 imagecolorallocate() 分配透明颜色。我第一眼没看懂。这是完全错误的做法。然而,imagecolorallocatealpha() 帮了我很多。

此外,在工作层上保存 alpha channel 之前,必须关闭 alpha 混合。但是,它必须在创建空白真彩色图像后立即完成,例如

  $im = imagecreatetruecolor($w, $h);
$alphacolor = imagecolorallocatealpha($img, $r, $g, $b, 127);
imagealphablending($im, false);
imagesavealpha($im, true);

这段代码是在缩小尺寸后在透明区域获得光滑角的关键。

毕竟这个函数是我写的

  function imageCreateCorners($sourceImageFile, $radius) {
# function body
}

我用几张图片对其进行了测试,它返回的图片每个背景颜色都带有平滑的角。

  imagepng(imageCreateCorners('jan_vesely_and_james_gist.jpg', 9), 'test.png');

输出

原图

enter image description here

在浏览器中(相同的 png 文件 'test.png')

enter image description here

它最终会返回完全透明的 alpha channel ,因此您可以在任何您想要的背景上使用该图像。

我差点忘了发布功能代码:)

函数 imageCreateCorners($sourceImageFile, $radius)

  function imageCreateCorners($sourceImageFile, $radius) {
# test source image
if (file_exists($sourceImageFile)) {
$res = is_array($info = getimagesize($sourceImageFile));
}
else $res = false;

# open image
if ($res) {
$w = $info[0];
$h = $info[1];
switch ($info['mime']) {
case 'image/jpeg': $src = imagecreatefromjpeg($sourceImageFile);
break;
case 'image/gif': $src = imagecreatefromgif($sourceImageFile);
break;
case 'image/png': $src = imagecreatefrompng($sourceImageFile);
break;
default:
$res = false;
}
}

# create corners
if ($res) {

$q = 10; # change this if you want
$radius *= $q;

# find unique color
do {
$r = rand(0, 255);
$g = rand(0, 255);
$b = rand(0, 255);
}
while (imagecolorexact($src, $r, $g, $b) < 0);

$nw = $w*$q;
$nh = $h*$q;

$img = imagecreatetruecolor($nw, $nh);
$alphacolor = imagecolorallocatealpha($img, $r, $g, $b, 127);
imagealphablending($img, false);
imagesavealpha($img, true);
imagefilledrectangle($img, 0, 0, $nw, $nh, $alphacolor);

imagefill($img, 0, 0, $alphacolor);
imagecopyresampled($img, $src, 0, 0, 0, 0, $nw, $nh, $w, $h);

imagearc($img, $radius-1, $radius-1, $radius*2, $radius*2, 180, 270, $alphacolor);
imagefilltoborder($img, 0, 0, $alphacolor, $alphacolor);
imagearc($img, $nw-$radius, $radius-1, $radius*2, $radius*2, 270, 0, $alphacolor);
imagefilltoborder($img, $nw-1, 0, $alphacolor, $alphacolor);
imagearc($img, $radius-1, $nh-$radius, $radius*2, $radius*2, 90, 180, $alphacolor);
imagefilltoborder($img, 0, $nh-1, $alphacolor, $alphacolor);
imagearc($img, $nw-$radius, $nh-$radius, $radius*2, $radius*2, 0, 90, $alphacolor);
imagefilltoborder($img, $nw-1, $nh-1, $alphacolor, $alphacolor);
imagealphablending($img, true);
imagecolortransparent($img, $alphacolor);

# resize image down
$dest = imagecreatetruecolor($w, $h);
imagealphablending($dest, false);
imagesavealpha($dest, true);
imagefilledrectangle($dest, 0, 0, $w, $h, $alphacolor);
imagecopyresampled($dest, $img, 0, 0, 0, 0, $w, $h, $nw, $nh);

# output image
$res = $dest;
imagedestroy($src);
imagedestroy($img);
}

return $res;
}

函数返回GD对象false


函数适用于纯 JPEG、GIF 和 PNG 图像。此外,它还适用于透明的 PNG 和 GIF。

关于php - 使用 imagecopyresampled() PHP GD 圆角透明_平滑_角,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5766865/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com