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

前端 未结 2 1997
渐次进展
渐次进展 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条回答
  • 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

    0 讨论(0)
  • 2021-01-14 07:21

    you can use ImageArtist which a GD wrapper created for making image manipulation insanely easy with php

    $overlay = new Overlay(720, 480, new Color(34,34,36));
    $w = $overlay->getWidth();
    $h = $overlay->getHeight();
    
    $mi = new CircularShape("./mi.jpg");
    $mi->scale(21);
    $mi->setAxises(60,60);
    $mi->build();
    
    $mali = new CircularShape("./mali.jpg");
    $mali->scale(60);
    $mali->setAxises(140,140);
    $mali->build();
    
    $bach = new CircularShape("./har.jpeg");
    $bach->scale(40);
    $bach->setAxises(80,80);
    $bach->build();
    
    $borderd = new CircularShape(new Overlay($bach->getWidth()+10,$bach->getHeight()+10,new Color(255,255,255)));
    $borderd->build();
    $bach = $borderd->merge($bach,5,5);
    
    $img = $overlay->merge($mi,$w/2 + 60,120);
    $img->merge($mali,170,60);
    $img->merge($bach,$w/2,200);
    
    $img->dump(); //this just for demo, but you can use other methods to save this to disk
    

    at the moment ImageArtist does not support borders but if you be little creative you can use an overlay instead. here is the output of the above code.

    0 讨论(0)
提交回复
热议问题