circularize an image with imagick

前端 未结 4 677
庸人自扰
庸人自扰 2020-12-10 00:33

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 th         


        
相关标签:
4条回答
  • 2020-12-10 00:50

    I stumbled upon this as I was searching for a similar solution for Ruby on Rails, notice that this Stackoverflow question uses vignette instead which seems to be a much simpler way to solve the problem.

    I used vignette to solve my problem with rounded images in Ruby on Rails using Dragonfly.

    0 讨论(0)
  • 2020-12-10 00:51

    Result of the code

    This works for me:

    <?php
    //$dims is an array with the width, height, x, y of the region in the rectangular image (whose path on disk is $tempfile)
    $tempfile = 'VDSlU.jpg';
    $outfile = 'blah.png';
    
    $circle = new Imagick();
    $circle->newImage(185.5, 185.5, 'none');
    $circle->setimageformat('png');
    $circle->setimagematte(true);
    $draw = new ImagickDraw();
    $draw->setfillcolor('#ffffff');
    $draw->circle(185.5/2, 185.5/2, 185.5/2, 185.5);
    $circle->drawimage($draw);
    
    $imagick = new Imagick();
    $imagick->readImage($tempfile);
    $imagick->setImageFormat( "png" );
    $imagick->setimagematte(true);
    $imagick->cropimage(185.5, 185.5, 253, 0);
    $imagick->compositeimage($circle, Imagick::COMPOSITE_DSTIN, 0, 0);
    $imagick->writeImage($outfile);
    $imagick->destroy();
    ?>
    
    <img src="blah.png">
    

    I always try to keep the code simple until I get it working and then add all the variables etc. That could be the problem or there could be a problem with your version of Imagick.

    It's namespaced

    Still do not know what it means! - I am getting a bit behind with php as I do not use it very much these days.

    0 讨论(0)
  • 2020-12-10 00:52

    There's also another workaround that I suggest here :

    // create an imagick object of your image
    $image = new \Imagick('/absolute/path/to/your/image');
    // crop square your image from its center (100px witdh/height in my example)
    $image->cropThumbnailImage(100, 100);
    // then round the corners (0.5x the width and height)
    $image->roundCorners(50, 50);
    // force the png format for transparency
    $image->setImageFormat("png");
    // write the new image
    $image->writeImage('/absolute/path/to/your/new/image');
    // done!
    

    Many thanks to all previous answers and contributors that lead me to this code!

    Feel free to test/comment my solution!

    0 讨论(0)
  • 2020-12-10 01:07

    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.

    0 讨论(0)
提交回复
热议问题