PHP GD如何圆形裁剪3个方形图像并合并为1个图像以保持透明度

PHP GD如何圆形裁剪3个方形图像并合并为1个图像以保持透明度,php,png,transparency,gd,Php,Png,Transparency,Gd,我有两个源图像,我想: 对每个图像进行圆形裁剪,使圆形外部透明 将所有图像合并/复制回目标透明图像 我已经试过了,但似乎无法保持最终图像的透明度 我正在努力实现这样的目标: 这是我得到的一个输出示例: 这是我的圆形裁剪函数: function create_circle( $img_path ) { // Attribution: by NerdsOfTech // Step 1 - Start with image as layer 1 (canvas).

我有两个源图像,我想:

  • 对每个图像进行圆形裁剪,使圆形外部透明
  • 将所有图像合并/复制回目标透明图像
  • 我已经试过了,但似乎无法保持最终图像的透明度

    我正在努力实现这样的目标:

    这是我得到的一个输出示例:

    这是我的圆形裁剪函数:

        function create_circle( $img_path ) {
        // Attribution: by NerdsOfTech
    
        // Step 1 - Start with image as layer 1 (canvas).
        if (! $img1 = $this->imageCreateFromAny( $img_path )) {
            return FALSE;
        }
    
        $x=imagesx($img1);
        $y=imagesy($img1);
    
    
        // Step 2 - Create a blank image.
        $img2 = imagecreatetruecolor($x, $y);
    
        $bg = imagecolorallocate($img2, 255,0,255, 127); // wierdo pink background
        // $bg = imagecolorallocate($img2, 0, 0, 0, 127 ); // white background
    
        imagefill($img2, 0, 0, $bg);
        imagecolortransparent($img2, $bg);
    
        // Step 3 - Create the ellipse OR circle mask.
        $e = imagecolorallocate($img2, 255, 255, 255); // black mask color
    
        // Draw a ellipse mask
        imagefilledellipse ($img2, ($x/2), ($y/2), $x, $y, $e);
    
        // OR
        // Draw a circle mask
        // $r = $x <= $y ? $x : $y; // use smallest side as radius & center shape
        // imagefilledellipse ($img2, ($x/2), ($y/2), $r, $r, $e);
    
        // Step 4 - Make shape color transparent
        imagecolortransparent($img2, $e);
    
        // Step 5 - Merge the mask into canvas with 100 percent opacity
        imagecopymerge($img1, $img2, 0, 0, 0, 0, $x, $y, 100);
    
        // Step 6 - Make outside border color around circle transparent
        imagecolortransparent($img1, $bg);
    
        /* Clean up memory */
        imagedestroy($img2);
    
        return $img1;
    }
    
    function show_png_from_image_object( $img_obj ) {
        header ( 'Content-Type: image/png' );
    
        /* Display PNG with max compression */
        imagepng ( $img_obj, NULL,  9, PNG_ALL_FILTERS);
        imagedestroy ( $img_obj );
    }
    
    以下是我的显示功能:

        function create_circle( $img_path ) {
        // Attribution: by NerdsOfTech
    
        // Step 1 - Start with image as layer 1 (canvas).
        if (! $img1 = $this->imageCreateFromAny( $img_path )) {
            return FALSE;
        }
    
        $x=imagesx($img1);
        $y=imagesy($img1);
    
    
        // Step 2 - Create a blank image.
        $img2 = imagecreatetruecolor($x, $y);
    
        $bg = imagecolorallocate($img2, 255,0,255, 127); // wierdo pink background
        // $bg = imagecolorallocate($img2, 0, 0, 0, 127 ); // white background
    
        imagefill($img2, 0, 0, $bg);
        imagecolortransparent($img2, $bg);
    
        // Step 3 - Create the ellipse OR circle mask.
        $e = imagecolorallocate($img2, 255, 255, 255); // black mask color
    
        // Draw a ellipse mask
        imagefilledellipse ($img2, ($x/2), ($y/2), $x, $y, $e);
    
        // OR
        // Draw a circle mask
        // $r = $x <= $y ? $x : $y; // use smallest side as radius & center shape
        // imagefilledellipse ($img2, ($x/2), ($y/2), $r, $r, $e);
    
        // Step 4 - Make shape color transparent
        imagecolortransparent($img2, $e);
    
        // Step 5 - Merge the mask into canvas with 100 percent opacity
        imagecopymerge($img1, $img2, 0, 0, 0, 0, $x, $y, 100);
    
        // Step 6 - Make outside border color around circle transparent
        imagecolortransparent($img1, $bg);
    
        /* Clean up memory */
        imagedestroy($img2);
    
        return $img1;
    }
    
    function show_png_from_image_object( $img_obj ) {
        header ( 'Content-Type: image/png' );
    
        /* Display PNG with max compression */
        imagepng ( $img_obj, NULL,  9, PNG_ALL_FILTERS);
        imagedestroy ( $img_obj );
    }
    
    我已经把头发拔了两天了,所以任何指点都将不胜感激


    谢谢,Jason。

    我编写了以下类来处理所有必需的图像处理:

    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);
        }
    }
    
    如前所述,该类将只处理PNG文件,但如果需要,您应该能够足够轻松地修改它

    示例类用法:

    // 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();
    
    这将产生下图(当然,嵌入此处时无法看到透明度,因此请尝试单独打开图像):

    我使用了以下两个源图像:

    您可以使用创建的GD包装器来使用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
    
    目前ImageArtist不支持边框,但如果您缺乏创意,可以使用覆盖。 下面是上述代码的输出


    看看是否可以help@tiGer-不知道这有什么帮助吗?你能添加
    create\u polarioid
    create\u circle
    show\u png\u from\u image\u object
    的代码吗?@tiGer-我已经更新了show\u png\u from\u image\u object函数。create_polaroid不相关,因为它未被使用。我这样调用函数:generate_collage($img_name_path_array,'CIRCLES');