PHP / GD, как скопировать кружок из одного изображения в другое? - PullRequest
6 голосов
/ 29 июня 2009

Есть ли достаточно простой способ скопировать круглую область из одного ресурса изображения в другой? Что-то вроде imagecopymerge за исключением кругов или овалов и т. Д.?
Если возможно, я хочу избегать использования предварительно созданных файлов изображений (должна быть возможна любая овальная форма), и, если используются прозрачные цвета, они, естественно, должны оставить оставшуюся часть изображения в покое.

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

1 Ответ

8 голосов
/ 29 июня 2009

Вы можете попробовать это:

  1. Начните с исходного изображения - $ img
  2. Скопируйте это изображение в png - $ copy
  3. Создайте изображение маски png области, которую вы хотите в круге / эллипсе (изображение 'magicpink' с черной формой на нем, с черным цветом, установленным на цвет альфа-прозрачности) - $ mask
  4. Скопируйте маску поверх поверх $ copy, сохраняя прозрачность Альфа
  5. Измените то, что вам нужно, на $ copy
  6. Copy $ copy обратно поверх $ img с сохранением прозрачности Alpha

    // 1. Start with the original image  
    $img = imagecreatefromjpeg("./original.jpg");  
    $img_magicpink = imagecolorallocatealpha($img, 255, 0, 255, 127);  
    //imagecolortransparent($img, $img_magicpink);  

    // (Get its dimensions for copying)  
    list($w, $h) = getimagesize("./original.jpg");  

    // 2. Create the first copy  
    $copy = imagecreatefromjpeg("./original.jpg");  
    imagealphablending($copy, true);  

    $copy_magicpink = imagecolorallocate($copy, 255, 0, 255);  
    imagecolortransparent($copy, $copy_magicpink);  

    // 3. Create the mask  
    $mask = imagecreatetruecolor($w, $h);  
    imagealphablending($mask, true);  

    // 3-1. Set the masking colours  
    $mask_black = imagecolorallocate($mask, 0, 0, 0);  
    $mask_magicpink = imagecolorallocate($mask, 255, 0, 255);  
    imagecolortransparent($mask, $mask_black);  
    imagefill($mask, 0, 0, $mask_magicpink);  

    // 3-2. Draw the circle for the mask  
    $circle_x = $w/2;  
    $circle_y = $h/2;  
    $circle_w = 150;  
    $circle_h = 150;  
    imagefilledellipse($mask, $circle_x, $circle_y, $circle_w, $circle_h, $mask_black);  

    // 4. Copy the mask over the top of the copied image, and apply the mask as an alpha layer  
    imagecopymerge($copy, $mask, 0, 0, 0, 0, $w, $h, 100);  


    // 5. Do what you need to do to the image area  
    // My example is turning the original image gray and leaving the masked area as colour  
    $x = imagesx($img);  
    $y = imagesy($img);  
    $gray = imagecreatetruecolor($x, $y);  
    imagecolorallocate($gray, 0, 0, 0);  
    for ($i = 0; $i > 16) & 0xFF;  
        $g = ($rgb >> 8) & 0xFF;  
        $b = $rgb & 0xFF;  
         //for gray mode $r = $g = $b  
        $color = max(array($r, $g, $b));  
        $gray_color = imagecolorexact($img, $color, $color,   $color);  
        imagesetpixel($gray, $i, $j, $gray_color);  
      }  
    }  

    // 6. Merge the copy with the origianl - maintaining alpha  
    imagecopymergegray($gray, $copy, 0, 0, 0, 0, $w, $h, 100);  
    imagealphablending($gray, true);  
    imagecolortransparent($gray, $mask_magicpink);  

    header('Content-Type: image/png');  
    imagepng($gray);  
    imagedestroy($gray);  
...