Прозрачное окружное обрезанное изображение с помощью PHP

Я хочу обрезать изображение круга с помощью PHP, но кажется, что у моего нового изображения есть несколько прозрачных пикселей. Конечно, я хочу ТОЛЬКО внешнюю область эллипса иметь прозрачный фон

Мой код приведен ниже:

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

……

Пример фактического сгенерированного изображения: введите описание изображения здесь

EDIT: функция generateTransparentImage не имеет ничего общего с приведенным выше кодом; эта функция генерирует это изображение: http://s7.postimage.org/byybq9163/Koala7_500x375_c_transparent.png

Следует отметить несколько вещей:

Как предположил @DainisAbols, для вашей прозрачности лучше использовать необычный цвет. Здесь вы используете черный цвет:

  $red = imagecolorallocate($mask, 0, 0, 0); imagecopymerge($image, $mask, 0, 0, 0, 0, $this->dst_w, $this->dst_h,100); imagecolortransparent($image, $red); 

Даже если ваш var называется красным, ваше значение RGB равно 0-0-0. Необычные цвета включают кричащий синий (0-0-255), кричащий зеленый (0-255-0), кричащий желтый (255-255-0), кричащий голубой (0-255-255) и кричащий розовый (255-0- 255). Красный цвет повсеместно распространен и не настолько яркий, поэтому я исключаю его из этих специальных цветов.

Тогда, даже если ваши изображения здесь и являются истинными цветами, это хорошая практика, чтобы выделить цвет для каждого изображения. В приведенном выше примере вы создаете переменную $red содержащую черную $mask , но вы используете ее как цвет прозрачности в $image .

Наконец, вы рисуете эллипс, который имеет тот же самый радиус, что и размер вашего изображения, поэтому вам нужно сделать изображение, imagefill каждый угол вашего изображения, а не только верхний левый. В вашем примере это работает, но это только потому, что вы выбрали черный цвет прозрачным.

Вот полная реализация.

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

Результат:

введите описание изображения здесь

Вы обрезаете и удаляете черный цвет (или устанавливаете черный как прозрачный). Так как ваше изображение имеет черный цвет, оно также удаляется.

Вместо удаления цвета попробуйте заменить цвет внешних слоев на, т. Е. Розовый, а затем установите прозрачность.

Я тоже не смогу сделать это с кодом Алена. Через некоторое время понимая, что делает каждая строка кода, вот мое исправление.

  //this creates a pink rectangle of the same size $mask = imagecreatetruecolor($imgwidth, $imgheight); $pink = imagecolorallocate($mask, 255, 0, 255); imagefill($mask, 0, 0, $pink); //this cuts a hole in the middle of the pink mask $black = imagecolorallocate($mask, 0, 0, 0); imagecolortransparent($mask, $black); imagefilledellipse($mask, $imgwidth/2, $imgheight/2, $imgwidth, $imgheight, $black); //this merges the mask over the pic and makes the pink corners transparent imagecopymerge($img, $mask, 0, 0, 0, 0, $imgheight, $imgheight); imagecolortransparent($img, $pink); imagepng($img, "my_circle.png");