用PHP透明圆裁剪图像 [英] Transparent Circle Cropped Image with 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屋!