2015-05-07 57 views
2

我有2个源图像和欲:PHP GD如何圆形作物3个方形图像和合并成1个图像保持透明

  1. 执行每个图像的圆形作物,与圆透明的外
  2. 将所有图像合并/复制回目标透明图像。

我试过many examples,但似乎无法在最终图像上保持透明度。

我想实现这样的事情: enter image description here

这是输出我得到的一个例子: enter image description here

这是我的circle_crop功能:

function create_circle($img_path) { 
    // Attribution: by NerdsOfTech 

    // Step 1 - Start with image as layer 1 (canvas). 
    if (! $img1 = $this->imageCreateFromAny($img_path)) { 
     return FALSE; 
    } 

    $x=imagesx($img1); 
    $y=imagesy($img1); 


    // Step 2 - Create a blank image. 
    $img2 = imagecreatetruecolor($x, $y); 

    $bg = imagecolorallocate($img2, 255,0,255, 127); // wierdo pink background 
    // $bg = imagecolorallocate($img2, 0, 0, 0, 127); // white background 

    imagefill($img2, 0, 0, $bg); 
    imagecolortransparent($img2, $bg); 

    // Step 3 - Create the ellipse OR circle mask. 
    $e = imagecolorallocate($img2, 255, 255, 255); // black mask color 

    // Draw a ellipse mask 
    imagefilledellipse ($img2, ($x/2), ($y/2), $x, $y, $e); 

    // OR 
    // Draw a circle mask 
    // $r = $x <= $y ? $x : $y; // use smallest side as radius & center shape 
    // imagefilledellipse ($img2, ($x/2), ($y/2), $r, $r, $e); 

    // Step 4 - Make shape color transparent 
    imagecolortransparent($img2, $e); 

    // Step 5 - Merge the mask into canvas with 100 percent opacity 
    imagecopymerge($img1, $img2, 0, 0, 0, 0, $x, $y, 100); 

    // Step 6 - Make outside border color around circle transparent 
    imagecolortransparent($img1, $bg); 

    /* Clean up memory */ 
    imagedestroy($img2); 

    return $img1; 
} 

这里的我通过调用circle_crop函数返回裁剪后的图像并将其合并到我的目标图像上,从而传递图像URL数组中的代码。

function generate_collage($img_name_path_array, $effect = 'POLAROID') { 
    $base_img_width = 800; 
    $base_img_height = 650; 

    if (empty($img_name_path_array)) { 
     error_log('Image name_path_array is blank?'.PHP_EOL); 
     return FALSE; 
    } 
    $effect = strtoupper($effect); 

    /* Create canvas */ 
    $collage_img = imagecreatetruecolor($base_img_width, $base_img_height); 
    imagealphablending($collage_img, false); 
    imagesavealpha($collage_img,true); 
    /* Create alpha channel for transparent layer */ 
    $trans_col=imagecolorallocatealpha($collage_img,255,255,255, 127); 
    /* Create overlapping transparent layer */ 
    imagefilledrectangle($collage_img,0,0,$base_img_width,$base_img_height,$trans_col); 

    /* Continue to keep layers transparent */ 
    imagealphablending($collage_img,true); 

    $size_reduction = .80; 
    $start_size = 100; 


    foreach ($img_name_path_array as $image_array) { 
     $img_text = $image_array[0]; 
     $img_path = $image_array[1]; 
     if (! empty($img_path)) { 
      switch ($effect) { 
       /* Add other collage image effects here */ 
       case 'POLAROID' : { 
        $temp_img = $this->create_polaroid($img_path, $img_text, TRUE); 
        break; 
       } 
       case 'CIRCLES' : { 
        // $temp_img = $this->circle_crop($img_path); 
        $temp_img = $this->create_circle($img_path); 
        break; 
       } 
       default : { 
        /* Default to polaroid for now */ 
        $temp_img = $this->create_polaroid($img_path, $img_text, TRUE); 
        break; 
       } 
      } 

      if ($temp_img) { 
       /* Get original height and width paramaters */ 
       $source_w = imagesx($temp_img); 
       $source_h = imagesy($temp_img); 

       /* Randomise X and Y coordinates */ 
       $random_x_pos = rand(0, (int) ($base_img_width * .66)); 
       $random_y_pos = rand(0, (int) ($base_img_height * .3)); 

       /* Randomise image size */ 
       $start_size = ($start_size * $size_reduction); 
       $random_img_size_ratio = $start_size/100; 

       /* Add generated image to base collage image */ 
       imagecopyresampled($collage_img, $temp_img, $random_x_pos, $random_y_pos, 0, 0, ($base_img_width * $random_img_size_ratio), ($base_img_height * $random_img_size_ratio), $source_w, $source_h); 

       imagecolortransparent($collage_img, $trans_col); 
       /* Keep transparent when saving */ 
       imagesavealpha($collage_img,true); 

       /* Memory clean up */ 
       imagedestroy($temp_img); 

       // break; 
      } 
     } 
    } 


    /* Now display PNG to browser */ 
    $this->show_png_from_image_object($collage_img); 
} 

这是我的显示功能:

function show_png_from_image_object($img_obj) { 
    header ('Content-Type: image/png'); 

    /* Display PNG with max compression */ 
    imagepng ($img_obj, NULL, 9, PNG_ALL_FILTERS); 
    imagedestroy ($img_obj); 
} 

我已经把我的头发了2天,所以任何指针将不胜感激。

谢谢,杰森。

+0

看看[这](http://stackoverflow.com/questions/29162633/create-ellipse-using-php)可以帮助 –

+0

@tiGer - 不知道如何帮助? – Jason

+0

请问您可以添加'create_polaroid','create_circle'和'show_png_from_image_object'的代码吗? –

回答

6

我写了下面的类来处理所有需要的图像处理:

class Img 
{ 
    public $img; 

    public $transparent; 

    public $width; 

    public $height; 

    public function __construct($img = null) 
    { 
     if (!empty($img)) { 
      $this->img = imagecreatefrompng($img); 
      $this->width = imagesx($this->img); 
      $this->height = imagesy($this->img); 
      $this->setTransparentColour(); 
     } 
    } 

    public function create($width, $height, $transparent) 
    { 
     $this->img = imagecreatetruecolor($width, $height); 
     $this->width = $width; 
     $this->height =$height; 

     $this->setTransparentColour(); 

     if (true === $transparent) { 
      imagefill($this->img, 0, 0, $this->transparent); 
     } 
    } 

    public function setTransparentColour($red = 255, $green = 0, $blue = 255) 
    { 
     $this->transparent = imagecolorallocate($this->img, $red, $green, $blue); 
     imagecolortransparent($this->img, $this->transparent); 
    } 

    public function circleCrop() 
    { 
     $mask = imagecreatetruecolor($this->width, $this->height); 
     $black = imagecolorallocate($mask, 0, 0, 0); 
     $magenta = imagecolorallocate($mask, 255, 0, 255); 

     imagefill($mask, 0, 0, $magenta); 

     imagefilledellipse(
      $mask, 
      ($this->width/2), 
      ($this->height/2), 
      $this->width, 
      $this->height, 
      $black 
     ); 

     imagecolortransparent($mask, $black); 

     imagecopymerge($this->img, $mask, 0, 0, 0, 0, $this->width, $this->height, 100); 

     imagedestroy($mask); 
    } 

    public function merge(Img $in, $dst_x = 0, $dst_y = 0) 
    { 
     imagecopymerge(
      $this->img, 
      $in->img, 
      $dst_x, 
      $dst_y, 
      0, 
      0, 
      $in->width, 
      $in->height, 
      100 
     ); 
    } 

    public function render() 
    { 
     header('Content-type: image/png'); 
     imagepng($this->img); 
    } 
} 

书面,类将只与PNG文件的工作,但你应该能够改变这一点很容易不够,如果需要的话。

实施例类用法:

// create a transparent base image that we will merge the cropped images into. 
$img = new Img(); 
$img->create(400, 400, true); 

// first image; crop and merge with base. 
$img2 = new Img('./crop_1.png'); 
$img2->circleCrop(); 
$img->merge($img2, 50, 50); 

// second image; crop and merge with base. 
$img3 = new Img('./crop_2.png'); 
$img3->circleCrop(); 
$img->merge($img3, 25, 200); 

$img->render(); 

这将导致下面的图像中的(当然,透明度是不可能看到这里嵌入时所以尝试分别打开图像):

Resultant image

我使用了这两个源图像:

Source image 1 Source image 2

0

你可以使用一个GD包装制作图像处理非常轻松用PHP

$overlay = new Overlay(720, 480, new Color(34,34,36)); 
$w = $overlay->getWidth(); 
$h = $overlay->getHeight(); 

$mi = new CircularShape("./mi.jpg"); 
$mi->scale(21); 
$mi->setAxises(60,60); 
$mi->build(); 

$mali = new CircularShape("./mali.jpg"); 
$mali->scale(60); 
$mali->setAxises(140,140); 
$mali->build(); 

$bach = new CircularShape("./har.jpeg"); 
$bach->scale(40); 
$bach->setAxises(80,80); 
$bach->build(); 

$borderd = new CircularShape(new Overlay($bach->getWidth()+10,$bach->getHeight()+10,new Color(255,255,255))); 
$borderd->build(); 
$bach = $borderd->merge($bach,5,5); 

$img = $overlay->merge($mi,$w/2 + 60,120); 
$img->merge($mali,170,60); 
$img->merge($bach,$w/2,200); 

$img->dump(); //this just for demo, but you can use other methods to save this to disk 

此刻ImageArtist不支持边界创建ImageArtist但如果你是小创意,你可以使用一个覆盖代替。 这里是上面代码的输出。

enter image description here