How to subtract one image from another?

IMagick is a native PHP extension to create and modify images using the ImageMagick API. ImageMagick Studio LLC did not write nor does it maintain the IMagick extension, however, IMagick users are welcome to discuss the extension here.
Post Reply
MrHamster
Posts: 3
Joined: 2017-02-26T07:29:21-07:00
Authentication code: 1151

How to subtract one image from another?

Post by MrHamster » 2017-02-26T08:16:41-07:00

Hello!
My goal is to subtract one transparent image from another (like delete watermark when I have this watermark as a picture)
I found ImageMagick script, but I don't know how to translate it to IMagick PHP code.
Can you help me with understanding this script or with translating it?

Code: Select all

convert ^
  image.png ^
  ( image-for-delete.png ^
    ( +clone -alpha extract +write mpr:WEX ) ^
    -compose Multiply -composite -negate ^
  ) ^
  -gravity center ^
  -compose ModulusAdd -composite ^
  ( mpr:WEX -negate ) ^
  -alpha off ^
  -compose DivideSrc -composite ^
  dewm.png
This script delete "image-for-delete.png" from "image.png"

Thank you!

snibgo
Posts: 9399
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: How to subtract one image from another?

Post by snibgo » 2017-02-26T09:31:25-07:00

I suggest you put it inside an "exec()". The command you showed uses Windows BAT syntax (eg line-ends are "^") and may need adjusting for PHP.
snibgo's IM pages: im.snibgo.com

Bonzo
Posts: 2850
Joined: 2006-05-20T08:08:19-07:00
Location: Cambridge, England

Re: How to subtract one image from another?

Post by Bonzo » 2017-02-26T12:37:10-07:00

That may not be possible as Imagick only supports some of the Imagemagick options. The simpler option would be to do as snibgo says and use exec() instead as you would only need to change a couple of things to allow it to run.

User avatar
fmw42
Posts: 22101
Joined: 2007-07-02T17:14:51-07:00
Location: Sunnyvale, California, USA

Re: How to subtract one image from another?

Post by fmw42 » 2017-02-26T12:39:20-07:00

I do not think Imagick supports mpr: in-memory images. You would need to change the whole syntax to create normal images. I think it can be done, but I am not an Imagick expert. Where did you find this code and how do you know it does what you want?

MrHamster
Posts: 3
Joined: 2017-02-26T07:29:21-07:00
Authentication code: 1151

Re: How to subtract one image from another?

Post by MrHamster » 2017-02-26T18:55:49-07:00

snibgo wrote:
2017-02-26T09:31:25-07:00
I suggest you put it inside an "exec()". The command you showed uses Windows BAT syntax (eg line-ends are "^") and may need adjusting for PHP.
Of course I don't want to make PHP do all of this for one command. Instead of '^' I can use number of commands. Instead of images in memory I hope to use variables in PHP.

You're the author of this script, because you wrote it in some post. Thanks for it😊
Can you describe every step this script do🙏 And I will search how to make it in Imagick.

snibgo
Posts: 9399
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: How to subtract one image from another?

Post by snibgo » 2017-02-26T19:30:35-07:00

Sorry, I don't use PHP or IMagick.
MrHamster wrote:... because you wrote it in some post.
I may have. Can you give the link to that post? The command looks like the inverse of "-compose Over -composite", more or less.

Each setting and operation is described in http://www.imagemagick.org/script/comma ... ptions.php

The command calculates:

Code: Select all

D = (R - S.Sa) / (1-Sa)
Where R is image.png (an opaque image), S is the colour of image-for-delete.png, Sa is the alpha of image-for-delete.png, and D is the output.

To be slightly more generalised, with current IM v6, add "-alpha off" before "-compose Multiply".

Does that command do what you need? You can test that at the command level.
snibgo's IM pages: im.snibgo.com

snibgo
Posts: 9399
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: How to subtract one image from another?

Post by snibgo » 2017-02-26T19:53:54-07:00

By way of example: suppose this watermark, wm_mark.png, which contains no opaque pixels, but different colours and opacities up to 50% ...
Image
... was composited over some unknown opaque image to make this watermarked result wm_toes_wm.png:
Image
... then we can find the unknown image:

Code: Select all

convert ^
  wm_toes_wm.png ^
  ( wm_mark.png ^
    ( +clone -alpha extract +write mpr:WEX ) ^
    -alpha off ^
    -compose Multiply -composite -negate ^
  ) ^
  -gravity center ^
  -compose ModulusAdd -composite ^
  ( mpr:WEX -negate ) ^
  -alpha off ^
  -compose DivideSrc -composite ^
  wm_dewm.png
Image
(For the web, two uploaded files are JPG, not PNG.)

If you provide a watermarked image and the watermark, I can test them with this command.
snibgo's IM pages: im.snibgo.com

MrHamster
Posts: 3
Joined: 2017-02-26T07:29:21-07:00
Authentication code: 1151

Re: How to subtract one image from another?

Post by MrHamster » 2017-02-26T23:21:35-07:00

snibgo wrote:
2017-02-26T19:30:35-07:00
The command calculates:

Code: Select all

D = (R - S.Sa) / (1-Sa)
Thanks!*-*
I think now I will be able to make it in PHP

In console it works great, I just should add some transparent white layer to original to avoid artefacts like in attachment.
Attachments
IMG_20170227_091924.jpg
Artefacts
IMG_20170227_091924.jpg (75.47 KiB) Viewed 6479 times

snibgo
Posts: 9399
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: How to subtract one image from another?

Post by snibgo » 2017-02-27T10:04:16-07:00

My command above removes watermarks only when the watermark contains no opaque pixels, and the original image is entirely opaque.

If the watermark contains opaque pixels, the job can't be done (because the watermark has overwritten pixels from the original).

If the original image is not entirely opaque, the job can be done, but the solution is more complex. I think it is:

Code: Select all

Da = (Ra - Sa) / (1-Sa)

D = (R*Ra - S*Sa*Da - S*Sa * (1-Da)) / (Da * (1-Sa))
... where Da is the alpha of the original.

EDIT: Corrected "R" to "R*Ra".

The second equation simplifies to:

Code: Select all

D = (R*Ra - S*Sa) / (Ra - Sa)
snibgo's IM pages: im.snibgo.com

Post Reply