Search code examples
phpimageimagemagickimagick

Merging two images via gradient


I am trying to merge two images in PHP, overlapping each other in the middle like in here : https://i.sstatic.net/ejdDQ.jpg

However, I am having no luck. On the ImageMagick page, they are using this method to do it in the command line: http://www.imagemagick.org/Usage/photos/#overlap But since I cannot use exec on my server, I have to do it somehow with the help of the imagick extension installed on the server (https://www.php.net/manual/en/book.imagick.php).

Is there any way to make this work?


Solution

  • Using the source files from the link and the code below generates the image:

    Imagick generated image

    //Load the images
    $left = new Imagick(realpath('../images/im/holocaust_tn.gif'));
    $right = new Imagick(realpath('../images/im/spiral_stairs_tn.gif'));
    $gradient = new Imagick(realpath('../images/im/overlap_mask.png'));
    
    //The right bit will be offset by a certain amount - avoid recalculating.
    $offsetX = $gradient->getImageWidth() - $right->getImageWidth();
    
    
    //When doing the fading of the images, ImageMagick uses "White == show image".
    //The gradient is setup with black on the left, white on the right. So the for
    //the left image we need to reverse the gradient to make it white on the left.
    $negativeGradient = clone $gradient;
    $negativeGradient->negateimage(false);
    
    //Fade out the left part
    $left->compositeimage(
        $negativeGradient,
        Imagick::COMPOSITE_COPYOPACITY,
        0, 0
    );
    
    //Fade out the right part - offset the gradient
    //to make it align in the final image
    $right->compositeimage(
        $gradient,
        Imagick::COMPOSITE_COPYOPACITY,
        -$offsetX, 0
    );
    
    //Create a new canvas to render everything in to.
    $canvas = new Imagick();
    $canvas->newImage($gradient->getImageWidth(), $gradient->getImageHeight(), new ImagickPixel('black'));
    
    //Blend left half into final image
    $canvas->compositeimage(
        $left,
        Imagick::COMPOSITE_BLEND,
        0, 0
    );
    
    //Blend Right half into final image
    $canvas->compositeimage(
        $right,
        Imagick::COMPOSITE_BLEND,
        $offsetX, 0
    );
    
    
    //Output the final image
    $canvas->setImageFormat('png');
    
    header("Content-Type: image/png");
    echo $canvas->getImageBlob();
    // And Robert is your father's brother.