Rounded transparent _smooth_ corners using imagecopyresampled() PHP GD

后端 未结 3 533
隐瞒了意图╮
隐瞒了意图╮ 2020-12-09 06:14

I need a script which makes rounded transparent corners on supplied image. I\'ve found one and it works good except the one thing: the applied corners do not look smooth. Th

3条回答
  •  渐次进展
    2020-12-09 06:29

    Improved code from @Wh1T3h4Ck5. This function take image and make round corners for it without waste memory. Also it must work faster on huge images. For example 1024*1024 image need 400MB temp image in original code. Now only 230 KB. (if you use radius 10 px).

    Function take GD image object, radius in px and return GD image object. Currently it is same as original GD image object.

    Function assume size of your image is bigger from radius. Exactly it need to be greater (or equal) from ($radius + 2)*2 on any side.

    Also function set imagealphablending to true for this image. If you need save into png, do not forgot set imagesavealpha to true.

    function roundCorners($source, $radius) {
        $ws = imagesx($source);
        $hs = imagesy($source);
    
        $corner = $radius + 2;
        $s = $corner*2;
    
        $src = imagecreatetruecolor($s, $s);
        imagecopy($src, $source, 0, 0, 0, 0, $corner, $corner);
        imagecopy($src, $source, $corner, 0, $ws - $corner, 0, $corner, $corner);
        imagecopy($src, $source, $corner, $corner, $ws - $corner, $hs - $corner, $corner, $corner);
        imagecopy($src, $source, 0, $corner, 0, $hs - $corner, $corner, $corner);
    
        $q = 8; # 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);
    
        $ns = $s * $q;
    
        $img = imagecreatetruecolor($ns, $ns);
        $alphacolor = imagecolorallocatealpha($img, $r, $g, $b, 127);
        imagealphablending($img, false);
        imagefilledrectangle($img, 0, 0, $ns, $ns, $alphacolor);
    
        imagefill($img, 0, 0, $alphacolor);
        imagecopyresampled($img, $src, 0, 0, 0, 0, $ns, $ns, $s, $s);
        imagedestroy($src);
    
        imagearc($img, $radius - 1, $radius - 1, $radius * 2, $radius * 2, 180, 270, $alphacolor);
        imagefilltoborder($img, 0, 0, $alphacolor, $alphacolor);
        imagearc($img, $ns - $radius, $radius - 1, $radius * 2, $radius * 2, 270, 0, $alphacolor);
        imagefilltoborder($img, $ns - 1, 0, $alphacolor, $alphacolor);
        imagearc($img, $radius - 1, $ns - $radius, $radius * 2, $radius * 2, 90, 180, $alphacolor);
        imagefilltoborder($img, 0, $ns - 1, $alphacolor, $alphacolor);
        imagearc($img, $ns - $radius, $ns - $radius, $radius * 2, $radius * 2, 0, 90, $alphacolor);
        imagefilltoborder($img, $ns - 1, $ns - 1, $alphacolor, $alphacolor);
        imagealphablending($img, true);
        imagecolortransparent($img, $alphacolor);
    
        # resize image down
        $dest = imagecreatetruecolor($s, $s);
        imagealphablending($dest, false);
        imagefilledrectangle($dest, 0, 0, $s, $s, $alphacolor);
        imagecopyresampled($dest, $img, 0, 0, 0, 0, $s, $s, $ns, $ns);
        imagedestroy($img);
    
        # output image
        imagealphablending($source, false);
        imagecopy($source, $dest, 0, 0, 0, 0, $corner, $corner);
        imagecopy($source, $dest, $ws - $corner, 0, $corner, 0, $corner, $corner);
        imagecopy($source, $dest, $ws - $corner, $hs - $corner, $corner, $corner, $corner, $corner);
        imagecopy($source, $dest, 0, $hs - $corner, 0, $corner, $corner, $corner);
        imagealphablending($source, true);
        imagedestroy($dest);
    
        return $source;
    }
    

提交回复
热议问题