Transparent Circle Cropped Image with PHP

后端 未结 3 1695
醉话见心
醉话见心 2020-12-17 05:03

I want to crop a circle image using PHP but it seems that my new image have some transparent pixels. Of course, I want ONLY the outside area of the ellipse to have backgroun

3条回答
  •  别那么骄傲
    2020-12-17 05:44

    There is several things to note :

    As @DainisAbols suggested, it should be better to take an unusual color to for your transparency. Here, you are using black :

        $red = imagecolorallocate($mask, 0, 0, 0);
        imagecopymerge($image, $mask, 0, 0, 0, 0, $this->dst_w, $this->dst_h,100);
        imagecolortransparent($image, $red);
    

    Even if your var is called red, your R-G-B value is 0-0-0. Uncommon colors include flashy blue (0-0-255), flashy green (0-255-0), flashy yellow (255-255-0), flashy cyan (0-255-255) and flashy pink (255-0-255). Red is quite common everywhere and is not that flashy so I exclude it from those special colors.

    Then, even if your images here are both true color's ones, that's a good practice to allocate a color for each image. In the example above, you create a $red variable containing black for $mask, but you're using it as transparency color in $image.

    Finally, you are drawing an ellipse which have the same radius as your image size, so you need to imagefill each corners of your image and not only the top-left's one. In your example it works, but this is only because you selected black to be the transparent color.

    Here is a full implementation.

    src_img = $img;
            $this->src_w = imagesx($img);
            $this->src_h = imagesy($img);
            $this->dst_w = imagesx($img);
            $this->dst_h = imagesy($img);
        }
    
        public function __destruct()
        {
            if (is_resource($this->dst_img))
            {
                imagedestroy($this->dst_img);
            }
        }
    
        public function display()
        {
            header("Content-type: image/png");
            imagepng($this->dst_img);
            return $this;
        }
    
        public function reset()
        {
            if (is_resource(($this->dst_img)))
            {
                imagedestroy($this->dst_img);
            }
            $this->dst_img = imagecreatetruecolor($this->dst_w, $this->dst_h);
            imagecopy($this->dst_img, $this->src_img, 0, 0, 0, 0, $this->dst_w, $this->dst_h);
            return $this;
        }
    
        public function size($dstWidth, $dstHeight)
        {
            $this->dst_w = $dstWidth;
            $this->dst_h = $dstHeight;
            return $this->reset();
        }
    
        public function crop()
        {
            // Intializes destination image
            $this->reset();
    
            // Create a black image with a transparent ellipse, and merge with destination
            $mask = imagecreatetruecolor($this->dst_w, $this->dst_h);
            $maskTransparent = imagecolorallocate($mask, 255, 0, 255);
            imagecolortransparent($mask, $maskTransparent);
            imagefilledellipse($mask, $this->dst_w / 2, $this->dst_h / 2, $this->dst_w, $this->dst_h, $maskTransparent);
            imagecopymerge($this->dst_img, $mask, 0, 0, 0, 0, $this->dst_w, $this->dst_h, 100);
    
            // Fill each corners of destination image with transparency
            $dstTransparent = imagecolorallocate($this->dst_img, 255, 0, 255);
            imagefill($this->dst_img, 0, 0, $dstTransparent);
            imagefill($this->dst_img, $this->dst_w - 1, 0, $dstTransparent);
            imagefill($this->dst_img, 0, $this->dst_h - 1, $dstTransparent);
            imagefill($this->dst_img, $this->dst_w - 1, $this->dst_h - 1, $dstTransparent);
            imagecolortransparent($this->dst_img, $dstTransparent);
    
            return $this;
        }
    
    }
    

    Demo :

    $img = imagecreatefromjpeg("test4.jpg");
    $crop = new CircleCrop($img);
    $crop->crop()->display();
    

    Result :

    enter image description here

提交回复
热议问题