Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Subtract two images to leave result - PHP

I have two images (both maps) one is a plain map and one is a map that had pins on it.

Image one

Image One

Image Two

Image Two

I'm trying to subtract them from each other so I'm left with just the pins as a transparent png.

I've had some success with this and have managed to get the pins as their own image, the problem is that the colours aren't quite right (see image 3).

Image Three

Image Three

I'm using Imagick to do this and my code is below

<?php

// load in the base image into Imagick
$imageOne = new Imagick('images/base-map.png');
$imageTwo = new Imagick('images/pins/location-7.png');

$imageOne->compositeImage($imageTwo, Imagick::COMPOSITE_DIFFERENCE, 0, 0);
$imageOne->paintTransparentImage($imageOne->getImagePixelColor(0, 0), 0, 5000);

header('Content-Type: image/png');

echo $imageOne;

Does anyone know how I can tidy/tweak this to make the colours match the original image?

Thanks!

like image 866
woolm110 Avatar asked Feb 04 '16 16:02

woolm110


3 Answers

You subtract from the pins as well, thats why they look different.

I'm not sure how to execute this in Imagick, but what you want to do is:

Subtract map from map with Pins, create a mask (put pin pixels 1, former map pixels 0) then multiply this with the map with pins. Then you are left with the pins.

This might help: http://www.imagemagick.org/script/fx.php

like image 127
Piglet Avatar answered Oct 06 '22 05:10

Piglet


You'll need to create a mask for this where its transparent for all the pins. More detailed here...

http://www.imagemagick.org/discourse-server/viewtopic.php?t=16279 http://www.imagemagick.org/discourse-server/viewtopic.php?f=1&t=15584&start=0

like image 39
gallickgunner Avatar answered Oct 06 '22 05:10

gallickgunner


I've managed to get this to work using the masking technique mentioned by Piglet and wandering-warrior and with help from this post as well

In case anyone else needs it the code is here:

<?php

$base = new Imagick('images/base-map.png'); // blank map
$mask = $base; // copy of this to create the mask with
$imageTwo = new Imagick('images/pins/location-7.png'); // image with pins on it

// create the mask
$mask->compositeImage($imageTwo, Imagick::COMPOSITE_DIFFERENCE, 0, 0);
$mask->paintTransparentImage($mask->getImagePixelColor(0, 0), 0, 5000);
$mask->compositeImage($mask, Imagick::COMPOSITE_DIFFERENCE, 0, 0);

// remove the mask from the image with pins
$imageTwo->compositeImage($mask, Imagick::COMPOSITE_DSTIN, 0, 0, Imagick::CHANNEL_ALPHA);
$imageTwo->paintTransparentImage('#000', 0, 5000);

header('Content-Type: image/png');
echo $imageTwo;

The mask looks like so mask

and the final output like so

enter image description here

Hopefully this will help someone else who needs it!

like image 21
woolm110 Avatar answered Oct 06 '22 03:10

woolm110