PHP GD How to circular crop 3 square images and merge into 1 image maintaining transparency

前端 未结 2 2020
渐次进展
渐次进展 2021-01-14 06:21

I have 2 source images and I want to:

  1. Do a circular crop of each image, with the outside of the circle transparent
  2. Merge/copy all images back onto a
2条回答
  •  旧时难觅i
    2021-01-14 07:03

    I've written the following class to handle all the required image processing:

    class Img
    {
        public $img;
    
        public $transparent;
    
        public $width;
    
        public $height;
    
        public function __construct($img = null)
        {
            if (!empty($img)) {
                $this->img = imagecreatefrompng($img);
                $this->width = imagesx($this->img);
                $this->height = imagesy($this->img);
                $this->setTransparentColour();
            }
        }
    
        public function create($width, $height, $transparent)
        {
            $this->img = imagecreatetruecolor($width, $height);
            $this->width = $width;
            $this->height =$height;
    
            $this->setTransparentColour();
    
            if (true === $transparent) {
                imagefill($this->img, 0, 0, $this->transparent);
            }
        }
    
        public function setTransparentColour($red = 255, $green = 0, $blue = 255)
        {
            $this->transparent = imagecolorallocate($this->img, $red, $green, $blue);
            imagecolortransparent($this->img, $this->transparent);
        }
    
        public function circleCrop()
        {
            $mask = imagecreatetruecolor($this->width, $this->height);
            $black = imagecolorallocate($mask, 0, 0, 0);
            $magenta = imagecolorallocate($mask, 255, 0, 255);
    
            imagefill($mask, 0, 0, $magenta);
    
            imagefilledellipse(
                $mask,
                ($this->width / 2),
                ($this->height / 2),
                $this->width,
                $this->height,
                $black
            );
    
            imagecolortransparent($mask, $black);
    
            imagecopymerge($this->img, $mask, 0, 0, 0, 0, $this->width, $this->height, 100);
    
            imagedestroy($mask);
        }
    
        public function merge(Img $in, $dst_x = 0, $dst_y = 0)
        {
            imagecopymerge(
                $this->img,
                $in->img,
                $dst_x,
                $dst_y,
                0,
                0,
                $in->width,
                $in->height,
                100
            );
        }
    
        public function render()
        {
            header('Content-type: image/png');
            imagepng($this->img);
        }
    }
    

    As written, the class will only work with PNG files but you should be able to modify this easily enough, if required.

    Example class usage:

    // create a transparent base image that we will merge the cropped images into.
    $img = new Img();
    $img->create(400, 400, true);
    
    // first image; crop and merge with base.
    $img2 = new Img('./crop_1.png');
    $img2->circleCrop();
    $img->merge($img2, 50, 50);
    
    // second image; crop and merge with base.
    $img3 = new Img('./crop_2.png');
    $img3->circleCrop();
    $img->merge($img3, 25, 200);
    
    $img->render();
    

    This will result in the below image (of course, the transparency is impossible to see when embedded here so try opening the image separately):

    Resultant image

    I used these two source images:

    Source image 1 Source image 2

提交回复
热议问题