Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
360 views
in Technique[技术] by (71.8m points)

php - circularize an image with imagick

Trying to take a rectangular photo, crop it into a square region, and then mask it into a circular with a transparent background.

//$dims is an array with the width, height, x, y of the region in the rectangular image (whose path on disk is $tempfile)

$circle = new Imagick();
$circle->newImage($dims['w'], $dims['h'], 'none');
$circle->setimageformat('png');
$circle->setimagematte(true);
$draw = new ImagickDraw();
$draw->setfillcolor('#ffffff');
$draw->circle($dims['w']/2, $dims['h']/2, $dims['w']/2, $dims['w']);
$circle->drawimage($draw);

$imagick = new Imagick();
$imagick->readImage($tempfile);
$imagick->setImageFormat( "png" );
$imagick->setimagematte(true);
$imagick->cropimage($dims['w'], $dims['h'], $dims['x'], $dims['y']);
$imagick->compositeimage($circle, Imagick::COMPOSITE_DSTIN, 0, 0);
$imagick->writeImage($tempfile);
$imagick->destroy();

The result is the rectangular image, uncropped and without being circularized. What am I doing wrong?

Example image: enter image description here

Example input for $dims = {"x":253,"y":0,"x2":438.5,"y2":185.5,"w":185.5,"h":185.5}

Rough expected output:

enter image description here

Image i'm getting looks roughly like the input image.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

For those with an older version of Imagick (setimagematte does not exist in version lower than 6.2.9), I came up with an easy solution. The thing here is to copy opacity from the mask to the original image.

Original Image:

enter image description here

Mask:

enter image description here

Result:

enter image description here

The code:

$base = new Imagick('original.jpg');
$mask = new Imagick('mask.png');

$base->compositeImage($mask, Imagick::COMPOSITE_COPYOPACITY, 0, 0);
$base->writeImage('result.png');

You could use an Imagick black circle as mask but I though it wasn't perfect so I used my own.

Of course you will certainly have to resize / crop your images but that's another story.

Hope this helps.

J.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...