Hard time combining level and dissolve commands into one.

Questions and postings pertaining to the usage of ImageMagick regardless of the interface. This includes the command-line utilities, as well as the C and C++ APIs. Usage questions are like "How do I use ImageMagick to create drop shadows?".
Post Reply
gimpeme
Posts: 6
Joined: 2017-08-11T11:09:45-07:00
Authentication code: 1151

Hard time combining level and dissolve commands into one.

Post by gimpeme » 2017-08-11T11:18:12-07:00

I have two images, IMG_0001.jpg and IMG_0002.jpg. I'm on ImageMagick 7.0.6 Q16 64-bit on Windows 7.

I want to take IMG_0002, adjust its white point to 15, set its transparency to 80%, stack it on top of IMG_0001, and output that, which I've figured out via:

Code: Select all

convert IMG_0002.jpg -level 0%,5% step1.jpg

composite -dissolve 80% step1.jpg IMG_0001.jpg step2.jpg
But I can't for the life of me combine these into one command. Any suggestions?

Also two side questions:
1) The level command for some reason will only work with percentages. So 0%,5% works but 0,15 (assuming scale of 0-255) doesn't... comparing with PS/GIMP, it sets the white point wayyyy lower.

2) How can I write this script as a file I can just drag and drop IMG_0001 and IMG_0002 onto and have the entire process work without me entering any commands? (It'll always be two sequential images, e.g. IMG_0473 and IMG_0474 stacked as mentioned above.)
Last edited by gimpeme on 2017-08-11T12:20:29-07:00, edited 2 times in total.

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

Re: Hard time combining level and dissolve commands into one.

Post by fmw42 » 2017-08-11T12:09:35-07:00

Don't use composite. Use convert .... -compose xxx -composite. You can only combine commands with convert. See
http://www.imagemagick.org/Usage/compose/#compose
http://www.imagemagick.org/Usage/basics/#parenthesis

So something like this in Unix syntax. For Windows, remove the \ characters. See http://www.imagemagick.org/Usage/windows/

Code: Select all

magick IMG_0001.jpg \( IMG_0002.jpg -level 0%,5% \) -define compose:args=80% -compose dissolve -composite step2.jpg
I may have the dissolve argument backwards so that it should be 20%, since convert and composite swap the order of the input images.

-level works with percentage or raw values. But raw values depend upon your IM compile Q level. For the default Q16 install, those values range from 0 to 65535. (For Q8, the values range from 0 to 255).

User avatar
GeeMack
Posts: 482
Joined: 2015-12-01T22:09:46-07:00
Authentication code: 1151
Location: Central Illinois, USA

Re: Hard time combining level and dissolve commands into one.

Post by GeeMack » 2017-08-11T12:11:39-07:00

gimpeme wrote:
2017-08-11T11:18:12-07:00
I want to take IMG_0002, adjust its white point to 15, set its transparency to 80%, stack it on top of IMG_0001, and output that. I've been able to do it in two steps via cmd line
The basic idea can be done in a single command that runs separate operations on the input images by isolating one of them in parentheses. Here's an example...

Code: Select all

convert input1.png ( input2.png -alpha set -level 0,15% ^
   -channel A -evaluate multiply 0.80 +channel ) -composite output.png
If you're using some flavor of *nix you'll need to change that continued line character from a caret "^" to a backslash "\" and escape the parentheses with backslashes "\( ... \)". The best method for running it in a script will depend on which OS you're working with and maybe which version of ImageMagick. You should let us know those things when you ask any question.

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

Re: Hard time combining level and dissolve commands into one.

Post by snibgo » 2017-08-11T12:46:02-07:00

gimpeme wrote:... on Windows 7 ... as a file I can just drag and drop ...
You want to drag-and-drop two files to one BAT script, which treats them differently. The programming is easy: they are %1 and %2. (Don't forget to double the % signs.) But dragging two files to a BAT file, and trying to get them in the right order, isn't easy. At least, I find it awkward.
snibgo's IM pages: im.snibgo.com

gimpeme
Posts: 6
Joined: 2017-08-11T11:09:45-07:00
Authentication code: 1151

Re: Hard time combining level and dissolve commands into one.

Post by gimpeme » 2017-08-12T11:55:42-07:00

Thanks fmw42 and GeeMack, I'll give those a try.
snibgo wrote:
2017-08-11T12:46:02-07:00
gimpeme wrote:... on Windows 7 ... as a file I can just drag and drop ...
You want to drag-and-drop two files to one BAT script, which treats them differently. The programming is easy: they are %1 and %2. (Don't forget to double the % signs.) But dragging two files to a BAT file, and trying to get them in the right order, isn't easy. At least, I find it awkward.
snibgo, there are two rules these images will always follow:
  1. The image with the largest file name (e.g. IMG_0595 > IMG_0594) will always be on top.
  2. The image on top will always be a nearly black image, while the other one will be a regular image with a large range of colors. (And as consequence, the file size will also be smaller for the image on top.)
Is there any way to use this to get the images in the right order?
Last edited by gimpeme on 2017-10-09T10:27:42-07:00, edited 2 times in total.

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

Re: Hard time combining level and dissolve commands into one.

Post by fmw42 » 2017-08-12T12:10:34-07:00

You would have to use your file system to test or sort the filenames for alphabetic order. Imagemagick cannot do that for you.

You can test the average brightness of each image before hand in a separate step by

convert image -format "%[fx:100*mean]" info:

you can set that up to be a test of two images to return 1 for first image brighter or 0 for first image darker by

convert image1 image2 -format "%[fx:(u.mean>=v.mean)?1:0]\n" info: | tail -n +2

User your OS to put the results into variables and then do an if test.


For example

Code: Select all

convert rose: rose1.png
convert rose: -level 50x100% rose2.png
Above rose2.png is darker than rose1.png

In Unix syntax:

Code: Select all

list="rose2.png
rose1.png"
new_list=`echo "$list" | sort`
echo "$new_list"
rose1.png
rose2.png
echo "$new_list" | convert @- -format "%[fx:(u.mean>=v.mean)?1:0]\n" info: | tail -n +2
1
Thus the first image, rose1.png from the new list is the brighter than the second. So now you know that the first image in the sorted list has a brighter value and the second image has a darker value. So if you take this list and process it to do the overlay, it should be correct.

Code: Select all

echo "$new_list" | convert @- -gravity center -compose over -composite result
You will have put the larger numbered image, which is darker over the smaller numbered image, which is brighter.

User avatar
GeeMack
Posts: 482
Joined: 2015-12-01T22:09:46-07:00
Authentication code: 1151
Location: Central Illinois, USA

Re: Hard time combining level and dissolve commands into one.

Post by GeeMack » 2017-08-12T17:43:55-07:00

gimpeme wrote:
2017-08-12T11:55:42-07:00
Is there any way to use this to get the images in the right order?
You can compare the brightness of a pair of images within an IM command, and adjust the order of the stack based on the result. With IM7 it would be a piece of cake. With IM6 it's not as pretty, but it can be done. Using IM 6.9.8-10, assuming your pairs of input images are the same size, a Windows BAT script like this would do the basic operation...

Code: Select all

@echo off

convert %1 %2 -set option:test %%[fx:(u.mean^<v.mean)*w] +append ^
   -virtual-pixel tile -distort affine "0,0 %%[test],0" -crop 2x1@ +repage ^
   ( -clone 1 -alpha set -level 0,15%% -channel A -evaluate multiply 0.80 +channel ) ^
   -delete 1 -composite output.png
This reads in both drag-and-dropped images and compares them. It sets a variable "test" to 0 if the first image is brighter, or to the width of the image if the first one is darker. Then it appends the images side by side.

Next it rolls the image to the left by "test" pixels, which results in swapping the left/right positions of the images only if the left one is darker. Crop the result in halves. The first one will be the brighter of the two input images and the second one is darker, regardless of the original input order.

After that you can clone the darker image inside some parentheses, adjust its levels and transparency any way you like, and finish by compositing that adjusted darker image over the original brighter image.

gimpeme
Posts: 6
Joined: 2017-08-11T11:09:45-07:00
Authentication code: 1151

Re: Hard time combining level and dissolve commands into one.

Post by gimpeme » 2017-10-09T11:37:29-07:00

GeeMack wrote:
2017-08-12T17:43:55-07:00
You can compare the brightness of a pair of images within an IM command, and adjust the order of the stack based on the result. With IM7 it would be a piece of cake.
How would you do this with IM7?

User avatar
GeeMack
Posts: 482
Joined: 2015-12-01T22:09:46-07:00
Authentication code: 1151
Location: Central Illinois, USA

Re: Hard time combining level and dissolve commands into one.

Post by GeeMack » 2017-10-09T18:16:31-07:00

gimpeme wrote:
2017-10-09T11:37:29-07:00
How would you do this with IM7?
A BAT script like this should work for IM7 and behave exactly the same as my IM6 example above...

Code: Select all

@echo off

magick %1 %2 -insert "%%[fx:u.mean>v.mean]" ^
   -level "0,%%[fx:t?15:100]%%" -compose dissolve -define compose:args=80 -composite output.png
The argument to "-insert" will swap the order of the images only if necessary to make sure the darker one comes second in the stack. The FX expression in the "-level" operation will level the second image to "0,15%" while not affecting the first image. The "-compose" settings and "-composite" operation will lay the second image at 80% opacity over the first.

gimpeme
Posts: 6
Joined: 2017-08-11T11:09:45-07:00
Authentication code: 1151

Re: Hard time combining level and dissolve commands into one.

Post by gimpeme » 2017-10-12T16:02:30-07:00

GeeMack wrote:
2017-10-09T18:16:31-07:00
The argument to "-insert" will swap the order of the images only if necessary to make sure the darker one comes second in the stack. The FX expression in the "-level" operation will level the second image to "0,15%" while not affecting the first image. The "-compose" settings and "-composite" operation will lay the second image at 80% opacity over the first.
You're amazing! Thank you. It works perfectly.

Interestingly it appears to be significantly slower than the non-sorting script (26 sec vs 4 sec). I'm guessing it has to sample every pixel of both images, so if it's a 24 MP image, it'll take quite a while.

Do you know if it'd be possible to use filename or file size to do the sorting instead to cut down on processing? File size because the darker image will always be smaller. Filename because they'll always have the same sequence (first one, IMG_0053.jpg = light, second one, IMG_0054.jpg = dark).

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

Re: Hard time combining level and dissolve commands into one.

Post by snibgo » 2017-10-12T19:35:40-07:00

I would do that in a script. For example (Windows BAT):

Code: Select all

if %1 GTR %2 (
  set imgA=%1
  set imgB=%2
) else (
  set imgA=%2
  set imgB=%1
)
Then use %imgA% and %imgB% in your convert or magick command.
snibgo's IM pages: im.snibgo.com

gimpeme
Posts: 6
Joined: 2017-08-11T11:09:45-07:00
Authentication code: 1151

Re: Hard time combining level and dissolve commands into one.

Post by gimpeme » 2017-10-13T12:48:50-07:00

Works perfectly! One very last question though! Here is what I have in my BAT file:

Code: Select all

@echo off

if %1 LSS %2 (
 set imgA=%1
 set imgB=%2
) else (
 set imgA=%2
 set imgB=%1
)
convert %imgA% ( %imgB% -alpha set -level 0,3840 -channel A -evaluate multiply 0.80 +channel ) -composite %~n2_overlay.jpg

exit
My very last issue is that previously, the output was saved in the same folder as the two images, with the 2nd file's name plus "_overlay" appended. That was because the %2 file's path could be expanded with %~n2. I'm not sure how to treat this command with "imgB" now. Is it even possible?

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

Re: Hard time combining level and dissolve commands into one.

Post by snibgo » 2017-10-13T12:56:17-07:00

Code: Select all

if %1 GTR %2 (
  set imgA=%1
  set imgB=%2
  set OUTFILE=%~n2_overlay.jpg
) else (
  set imgA=%2
  set imgB=%1
  set OUTFILE=%~n1_overlay.jpg
)
... then use %OUTFILE% in the convert.
snibgo's IM pages: im.snibgo.com

gimpeme
Posts: 6
Joined: 2017-08-11T11:09:45-07:00
Authentication code: 1151

Re: Hard time combining level and dissolve commands into one.

Post by gimpeme » 2017-10-13T15:24:55-07:00

YES! This is now working perfectly. Thank you so much for the help! Especially to snibgo and GeeMack... you guys pretty much solved it all.

For anybody who needs similar functionality from ImageMagick, here is the final .bat script:

Code: Select all

@echo off

if %1 LSS %2 (
 set imgA=%1
 set imgB=%2
 set output=%~n2_overlay.jpg
) else (
 set imgA=%2
 set imgB=%1
 set output=%~n1_overlay.jpg
)
convert %imgA% ( %imgB% -alpha set -level 0,3840 -channel A -evaluate multiply 0.80 +channel ) -composite %output%

exit

Post Reply