2016-12-26 100 views
1

我需要知道如何使用Imagick蒙版任何方形圖像。這裏是我到目前爲止的代碼,但圖像只是沒有得到正確蒙:生成Imagick圖像蒙版圖像

獲取圖像

$srcFile = 'filename.png'; 
$image = new Imagick($srcFile); 

裁剪圖像,以方

$d = $image->getImageGeometry(); 
$src_width = $d['width']; 
$src_height = $d['height']; 
$thumbSize = min(max($src_width, $src_height), abs($thumbSize));   
if ($src_width < $src_height) { 
    $image->cropImage($src_width, $src_width, 0, (($src_height - $src_width)/2)); 
} else { 
    $image->cropImage($src_height, $src_height, (($src_width - $src_height)/2), 0); 
} 

調整圖像大小

$image->thumbnailImage($thumbSize, $thumbSize, 1); 

作物/掩碼圖像與貝塞爾曲線形狀

$image->compositeImage(bezier($thumbSize, $thumbSize), Imagick::COMPOSITE_COPYOPACITY, 0, 0); 

貝塞爾函數創建的形狀看起來像這樣:

bezier mask shape

function bezier($width, $height) { 
    $fillColor = "#000"; 
    $draw = new ImagickDraw(); 

填寫未屏蔽部分黑色

$fillColor = new ImagickPixel($fillColor); 
    $draw->setFillColor($fillColor); 
    $smoothPointsSet = [ 
     [ 
      ['x' => 0.0 * $width, 'y' => 0.5 * $width], 
      ['x' => 0.0 * $width, 'y' => 0.905 * $width], 
      ['x' => 0.095 * $width, 'y' => 1.0 * $width], 
      ['x' => 0.5 * $width, 'y' => 1.0 * $width] 
     ], [ 
      ['x' => 0.5 * $width, 'y' => 1.0 * $width], 
      ['x' => 0.905 * $width, 'y' => 1.0 * $width], 
      ['x' => 1.0 * $width, 'y' => 0.905 * $width], 
      ['x' => 1.0 * $width, 'y' => 0.5 * $width] 
     ], [ 
      ['x' => 1.0 * $width, 'y' => 0.5 * $width], 
      ['x' => 1.0 * $width, 'y' => 0.095 * $width], 
      ['x' => 0.905 * $width, 'y' => 0.0 * $width], 
      ['x' => 0.5 * $width, 'y' => 0.0 * $width] 
     ], [ 
      ['x' => 0.5 * $width, 'y' => 0.0 * $width], 
      ['x' => 0.095 * $width, 'y' => 0.0 * $width], 
      ['x' => 0.0 * $width, 'y' => 0.095 * $width], 
      ['x' => 0.0 * $width, 'y' => 0.5 * $width] 
     ] 
    ]; 

    foreach ($smoothPointsSet as $points) { 
     $draw->bezier($points); 
    } 

貝塞爾點沒有填補中間的方形人工手動

$points = [ 
     ['x' => $width * 0.5, 'y' => 0.0], 
     ['x' => 0.0, 'y' => $height * 0.5], 
     ['x' => $width * 0.5, 'y' => $height], 
     ['x' => $width, 'y' => $height * 0.5] 
    ]; 
    $draw->polygon($points); 

填充它複製抽屜圖像到一個新的透明Imagick圖像

$imagick = new Imagick(); 
    $imagick->newImage($width, $width, "none"); 

從這裏開始,我嘗試過不同的屬性。我沒有得到任何令人滿意的結果 - 圖像幾乎總是不被掩蓋。

#$imagick->setImageAlphaChannel(Imagick::ALPHACHANNEL_SHAPE); 
    #$imagick->setImageFormat("png"); 

    $imagick->drawImage($draw); 

    #$imagick->setImageMatte(false); 

    return $imagick; 
} 

我會很高興,如果我能知道問題所在和如何解決它。我發現SO各種答案的並沒有爲我工作:

使用$dude->setImageMatte(1); Using a transparent PNG as a clip mask

使用$base->compositeImage($mask, Imagick::COMPOSITE_DSTIN, 0, 0, Imagick::CHANNEL_ALPHA); How to use Imagick to merge and mask images?

不幸的是我解決不了問題。

回答

0

問題是圖像存儲爲JPEG,所以透明部分變成黑色。這是我使用的代碼:

$mask = bezier($thumbSize, $thumbSize); 

// Copy opacity mask 
if ($image->getImageMatte()) { 
    $image->compositeImage($mask, Imagick::COMPOSITE_DSTIN, 0, 0, Imagick::CHANNEL_ALPHA); 
} else { 
    $image->compositeImage($mask, Imagick::COMPOSITE_COPYOPACITY, 0, 0); 
} 

$image->setImageBackgroundColor(new ImagickPixel('white')); 
#$image->setImageAlphaChannel(Imagick::ALPHACHANNEL_DEACTIVATE); 
$image = $image->flattenImages(); 

在功能貝塞爾:

$imagick = new Imagick(); 
$imagick->newImage($width, $width, "none"); 
$imagick->setImageBackgroundColor(new ImagickPixel('transparent')); 
#$imagick->setImageAlphaChannel(Imagick::ALPHACHANNEL_SHAPE); 
$imagick->setImageFormat("png"); 

//Render the draw commands in the ImagickDraw object 
//into the image. 
$imagick->drawImage($draw); 
$imagick->negateImage(FALSE); 


return $imagick; 
+0

這是一個值得主意張貼到ImageMagick的郵件列表,或打他們的IRC頻道,或任何其直接接觸的方法是爲了讓他們知道,圖像magick顯然不會警告用戶,當他們保存圖像的格式不支持使用的功能。用位圖中的alpha通道保存圖像爲JPEG應至少爲您提供控制檯警告,這將允許您立即發現並解決問題。 –

+0

「,讓他們知道圖像magick顯然不會警告用戶,當他們保存圖像的格式」這可能是設計。 ImageMagick公開的C api背後的哲學是做用戶告訴它做的事情,假設他們知道自己在做什麼。將Jpeg保存爲透明圖像是一種常見的事情(有些時候),所以它只是做它,而不是懷疑用戶的意圖。 – Danack