2016-12-26 2 views
1

Ich muss wissen, wie es möglich ist, jedes quadratische Bild mit Imagick zu maskieren. Hier ist der Code, den ich so weit, aber das Bild ist einfach nicht richtig erhalten maskiert:Bilder mit einem generierten Bild imagick maskieren

Holen Sie sich das Bild

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

Crop das Bild auf Platz

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

Größe ändern das Bild

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

Crop/Maske des Bildes mit der Bezier-Form

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

Die Bezier-Funktion eine Form suchen, wie dies schafft:

bezier mask shape

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

Füllen Sie den unmaskierten Teil mit schwarzer Farbe

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

Bezier-Punkte ein Quadrat in der Mitte nicht manuell

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

Kopieren Sie die Schublade Bild zu einem neuen transparenten Imagick Bild

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

füllen, so füllen Ab hier habe ich mit verschiedenen Eigenschaften experimentiert. Ich habe kein befriedigendes Ergebnis bekommen - das Bild wird fast immer nicht maskiert.

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

    $imagick->drawImage($draw); 

    #$imagick->setImageMatte(false); 

    return $imagick; 
} 

würde ich mich sehr freuen, wenn ich weiß, könnte, wo das Problem liegt und wie man es beheben. Ich fand verschiedene Antworten auf SO, die nicht für mich arbeiten:

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

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

Leider konnte ich das Problem nicht lösen.

Antwort

0

Das Problem war, dass Bilder als JPEG gespeichert wurden, so dass der transparente Teil schwarz wurde.Dies ist der Code, den ich verwenden:

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

In Funktion Bezier:

$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

Es ist eine lohnenswerte Idee zur imagemagick Mailing-Liste zu veröffentlichen, oder ihren IRC-Kanal treffen, oder was auch immer ihre Methode des direkten Kontakts ist, um sie wissen zu lassen, dass image magick die Benutzer nicht warnt, wenn sie Bilder in einem Format speichern, das die verwendeten Funktionen nicht unterstützt. Wenn Sie ein Bild mit einem Alphakanal in der Bitmap als JPEG speichern, sollten Sie mindestens eine Konsolenwarnung erhalten, mit der Sie das Problem sofort erkennen und beheben können. –

+0

"um sie wissen zu lassen, dass image magick anscheinend keine Benutzer warnt, wenn sie Bilder in einem Format speichern" Das ist wahrscheinlich von Entwurf. Die Philosophie hinter der CAPI, die ImageMagick entlarvt, besteht darin, das zu tun, was der Benutzer sagt, unter der Annahme, dass sie wissen, was sie tun. Speichern eines Bildes mit Transparenz als Jpeg ist eine normale Sache (etwas Zeit), also tut es es einfach, anstatt zu zweifeln, was der Benutzer beabsichtigt hat. – Danack

Verwandte Themen