Прозрачный круг обрезанное изображение с 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');

......

Пример реального сгенерированного изображения здесь:

РЕДАКТИРОВАТЬ: функция generateTransparentImage не имеет ничего общего с кодом, перечисленным выше; эта функция генерирует это изображение:http://s7.postimage.org/byybq9163/Koala7_500x375_c_transparent.png

 hakre18 окт. 2012 г., 13:18
Если вы хотите, чтобы другие играли с вашим кодом, вы также должны поделиться исходным изображением. Также кодgenerateTransparentImage скрыт, поэтому другие тоже не могут воспроизвести.
 hakre18 окт. 2012 г., 13:26
возможный дубликатPHP - маска многоугольника над изображением - Если вы не хотите использовать библиотеку, исходный код Wideimage является свободным программным обеспечением, поэтому вы можете перенести его в свое приложение. В противном случае, существует множество существующих вопросов, которые показывают различные другие способы, как это сделать, бесплатно посмотреть вокруг:stackoverflow.com/search?q=%5Bphp%5D+%5Bgd%5D+mask

Ответы на вопрос(3)

я того, что делает каждая строка кода, вот мое исправление ..

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

Как предположил @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 называется красным, ваше значение R-G-B равно 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();

Результат:

 Alain Tiemblo22 апр. 2014 г., 14:43
код вышеприведенного демо:pastebin.com/xe07p34e
 Alain Tiemblo22 апр. 2014 г., 14:20
привет, я только что проверил, и я подтверждаю, что прозрачность работает здесь
 Ravi Jethva22 апр. 2014 г., 10:44
его не прозрачный его дают белые цвета в фоновом режиме
 Alain Tiemblo22 апр. 2014 г., 14:40
доказательство:home.fuz.org/tests/test-circle-crop.php (используйте любой цвет фона, чтобы проверить, является ли сгенерированное изображение прозрачным)

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

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

Ваш ответ на вопрос