Page 1 of 1

Hard time combining level and dissolve commands into one.

Posted: 2017-08-11T11:18:12-07:00
by gimpeme
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.)

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

Posted: 2017-08-11T12:09:35-07:00
by fmw42
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).

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

Posted: 2017-08-11T12:11:39-07:00
by GeeMack
gimpeme wrote: 2017-08-11T11:18:12-07:00I 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.

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

Posted: 2017-08-11T12:46:02-07:00
by snibgo
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.

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

Posted: 2017-08-12T11:55:42-07:00
by gimpeme
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?

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

Posted: 2017-08-12T12:10:34-07:00
by fmw42
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.

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

Posted: 2017-08-12T17:43:55-07:00
by GeeMack
gimpeme wrote: 2017-08-12T11:55:42-07:00Is 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.

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

Posted: 2017-10-09T11:37:29-07:00
by gimpeme
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?

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

Posted: 2017-10-09T18:16:31-07:00
by GeeMack
gimpeme wrote: 2017-10-09T11:37:29-07:00How 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.

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

Posted: 2017-10-12T16:02:30-07:00
by gimpeme
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).

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

Posted: 2017-10-12T19:35:40-07:00
by snibgo
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.

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

Posted: 2017-10-13T12:48:50-07:00
by gimpeme
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?

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

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

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.

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

Posted: 2017-10-13T15:24:55-07:00
by gimpeme
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