用PHP透明圆裁剪图像 [英] Transparent Circle Cropped Image with PHP

查看:169
本文介绍了用PHP透明圆裁剪图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用PHP裁剪圆形图像,但似乎我的新图像有一些透明像素。当然,我只希望椭圆的外部区域背景透明

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 background transparent

我的代码如下:

        $image = imagecreatetruecolor($this->dst_w, $this->dst_h);
        imagealphablending($image,true);
        imagecopy ( $image , $image_s , 0, 0, $this->src_x, $this->src_y, $this->dst_w, $this->dst_h );
        $mask = imagecreatetruecolor($this->src_x, $this->src_y);
        $mask = imagecreatetruecolor($this->dst_w, $this->dst_h);
        $transparent = imagecolorallocate($mask, 255, 0, 0);
        imagecolortransparent($mask, $transparent);
        imagefilledellipse($mask, $this->dst_w/2, $this->dst_h/2, $this->dst_w, $this->dst_h, $transparent);
        $red = imagecolorallocate($mask, 0, 0, 0);
        imagecopymerge($image, $mask, 0, 0, 0, 0, $this->dst_w, $this->dst_h,100);
        imagecolortransparent($image, $red);
        imagefill($image,0,0, $red);

        if ($ext=="jpg" || $ext=="jpeg") {
            imagejpeg($image, $this->croppedImage);
        } else if ($ext=="png") {
            imagepng($image, $this->croppedImage);
        }           
        imagedestroy($image);
        imagedestroy($mask);
        // <------- END generate cropped Image ------->

        // <------- START generate transparent Image ------->               
        $this->generateTransparentImage('circle');

......

实际生成的图像的示例如下:

An example of actual generated image is here:

编辑:generateTransparentImage函数与上面列出的代码无关;此函数生成此图像:
http://s7.postimage.org/byybq9163/ Koala7_500x375_c_transparent.png

generateTransparentImage function has nothing to do with the code listed above; this function generate this image: http://s7.postimage.org/byybq9163/Koala7_500x375_c_transparent.png

推荐答案

有几点需要注意:

正如@DainisAbols建议的那样,为了透明度而采取不寻常的颜色应该更好。在这里,你使用黑色:

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);

即使你的var被称为红色,你的R-G-B值也是0-0-0。不常见的颜色包括华丽的蓝色(0-0-255),华丽的绿色(0-255-0),华丽的黄色(255-255-0),华丽的青色(0-255-255)和华丽的粉红色(255-0- 255)。红色在各处都很常见,并不是那么华丽,所以我把它从那些特殊的颜色中排除。

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.

然后,即使这里的图像都是真彩色图像,为每个图像分配颜色也是一种很好的做法。在上面的示例中,您为 $ mask 创建了一个 $ red 变量,但是您将其用作 $ image 中的透明度颜色。

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.

最后,您绘制的椭圆与图像大小的半径相同,因此您需要 imagefill 图像的每个角落,而不仅仅是左上角的角落。在你的例子中它可以工作,但这只是因为你选择黑色作为透明色。

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.

这是一个完整的实现。

<?php

class CircleCrop
{

    private $src_img;
    private $src_w;
    private $src_h;
    private $dst_img;
    private $dst_w;
    private $dst_h;

    public function __construct($img)
    {
        $this->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;
    }

}

演示:

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

结果:

这篇关于用PHP透明圆裁剪图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆