Page 1 of 2

How to combine 2 images?

Posted: 2018-10-05T11:34:50-07:00
by imanasya
Is it possible write a code for ImageMagick which takes 2 images, scales them to max size (w or h) keeping aspect ratio and creates combined image placing first one on top of the second? Maintaining best possible jpg quality with bicubic automatic scaling similar to Photoshop? I have ImageMagick 7.0.8-12 Q16 x64 installed on Windows 10. Inputs are jpg without transparency. Aspect ratio, width and height of every image may vary. If h>w fill 2 holes with white.

https://i.stack.imgur.com/7gOTH.png
https://i.stack.imgur.com/xXoWF.png

Re: How to combine 2 images?

Posted: 2018-10-05T12:49:14-07:00
by fmw42
red:
Image

green:
Image

This IM 7 command should work for both Unix and Windows. If in a bat file, I believe you need to double % to %5

Code: Select all

magick red.jpg green.jpg -set option:ww "%[fx:max(u.w,v.w)]" -set option:hh "%[fx:max(u.h,v.h)]" -resize "%[ww]x%[hh]" -background white -gravity center -append -quality 100 red_green.jpg
Image

Re: How to combine 2 images?

Posted: 2018-10-06T00:57:55-07:00
by imanasya
Thank you very much! I put this line in my bat file:

Code: Select all

magick image_0.jpg image_1.jpg -set option:ww "%%[fx:max(u.w,v.w)]" -set option:hh "%%[fx:max(u.h,v.h)]" -filter Catrom -resize "%%[ww]x%%[hh]" -unsharp 0x1+1+0.05 -background white -gravity center -append -quality 100 combined.jpg
and it works. But it doesn't resize to max dimension. I take img0 356x800 and img1 596x770. Combined img is 569x1570. It does not scale up img1 596x770 to max value 800=max{356,800,596,770} img1 619x800. The combined image must be 619x1600 in this case.
Is it possible to add -fuzz 3% -trim +repage in the beginning? For some reason it shows error.

Re: How to combine 2 images?

Posted: 2018-10-06T03:32:35-07:00
by imanasya
As I see this line scales up the first image only. How can I divide what to do with the first image and what to do with the second?

Re: How to combine 2 images?

Posted: 2018-10-06T11:12:32-07:00
by fmw42
I am not sure I fully understand what you want, but try this as the basic geometry command. You can add your own filtering for resize as desired and any unsharp masking. I just want to be sure I understand the resizing issue.

red:
Image

green:
Image

Unix and non-bat Windows syntax:

Code: Select all

magick red2.jpg green2.jpg -set option:dim "%[fx:max(max(u.w,v.w),max(u.h,v.h))]" -resize "%[dim]x%[dim]" -background white -gravity center -append -quality 100 red_green2.jpg
Image

This will resize both images so that both have their max dimensions set to the largest dimension of the two images (preserving aspect ratio). The complication is when one images has its largest dimension in width and the other in height.

If this is not what you want, the please clarify further or give me another example.

Is it possible to add -fuzz 3% -trim +repage in the beginning? For some reason it shows error.
What error message? That should work fine if you put that right after reading the images, if you want both trimmed. Recall that for Windows bat all % need to be doubled, so -fuzz 3% should be 3%%.

Re: How to combine 2 images?

Posted: 2018-10-06T11:44:10-07:00
by imanasya
Thank you.
I have a code on windows cmd with ffmpeg which describes what I'm trying to do:

Code: Select all

if !w1! LSS !h1! (                  rem w1<h1  356<800
  set "p1=oh/mdar:h='max(ih,main_h)'"                  rem w=356:h=800
  if !w2! LSS !h2! (                  rem w1<h1 & w2<h2  356<800 & 596<770
    set "p2=oh/mdar:h='max(ih,main_h)'"                  rem w=596*800/700=619:h=800
  ) else (                  rem w1<h1 & w2>=h2
    set "p2='max(iw,main_w)':h=ow/mdar"
  )
) else (                  rem w1>=h1
  set "p1='max(iw,main_w)':h=ow/mdar"
  if !w2! LSS !h2! (                  rem w1>=h1 & w2<h2
    set "p2=oh/mdar:h='max(ih,main_h)'"
  ) else (                  rem w1>=h1 & w2>=h2
    set "p2='max(iw,main_w)':h=ow/mdar"
  )  
)

Re: How to combine 2 images?

Posted: 2018-10-06T11:51:55-07:00
by fmw42
Was my last command not what you needed?

Sorry, I am not a Windows user or programmer. If you can explain what you want functionally or mathematically or in pseudocode, perhaps I can help. Otherwise, one of the Windows users might be able willing to help you further.

Re: How to combine 2 images?

Posted: 2018-10-06T12:22:11-07:00
by fmw42
scales them to max size (w or h) keeping aspect ratio and creates combined image placing first one on top of the second?

If h>w fill 2 holes with white.
These two requirement are not consistent as I understand it.

The first says make both images have either width or height equal to the largest width or height.

The second seems to imply that you really only want to scale the heights.

Please clarify.

Re: How to combine 2 images?

Posted: 2018-10-06T13:15:08-07:00
by fmw42
If you need the width padded with white to the same dimension as each image's final resized height, then you can do one of these two depending upon what you want. Basically just add -extent Wx.

This resizes the larger dimension of each image to the largest dimension of both images.

Code: Select all

magick red2.jpg green2.jpg -set option:dim "%[fx:max(max(u.w,v.w),max(u.h,v.h))]" -resize "%[dim]x%[dim]" -background white -gravity center -append -gravity north -extent "%[dim]x" -quality 100 red_green3.jpg
Image

This resizes the height of each image to the largest dimension of both images.

Code: Select all

magick red2.jpg green2.jpg -set option:dim "%[fx:max(max(u.w,v.w),max(u.h,v.h))]" -resize "x%[dim]" -background white -gravity center -append -gravity north -extent "%[dim]x" -quality 100 red_green4.jpg
Image

Re: How to combine 2 images?

Posted: 2018-10-06T13:44:20-07:00
by imanasya
fmw42, thank you very much, you are a genius! Half of the page windows code you wrote in one line. Could you explain a little bit: this line finding max value (w1,w2,h1,h2)

Code: Select all

-set option:dim "%%[fx:max(max(u.w,v.w),max(u.h,v.h))]"
Then how this operator

Code: Select all

-resize "%%[dim]x%%[dim]"
manages to identify which side w or h it has to increase to max value?
Finally, I stopped at this:

Code: Select all

magick image_0.jpg image_1.jpg -fuzz 2%% -trim +repage -set option:dim "%%[fx:max(max(u.w,v.w),max(u.h,v.h))]" -filter Catrom -resize "%%[dim]x%%[dim]" -unsharp 0x1+0.8+0.05 -background white -gravity center -append -quality 100 combined.jpg
Default unsharp gain seams too hard for me. Can I make resample or jpg quality better?
Is it possible to add if (w1>h1 and w2<h2 after the trim) do the line above, else do this:

Code: Select all

magick image_0.jpg -quality 100 first.jpg

Re: How to combine 2 images?

Posted: 2018-10-06T14:04:25-07:00
by fmw42
-set option:dim "%%[fx:max(max(u.w,v.w),max(u.h,v.h))]"
In Imagemagick, the fx function max() only takes two argument. So I took the max of the two height, and the max of the two width and then the max of the two max's.
-resize "%%[dim]x%%[dim]"
This will take whichever dimension (width or height of an image is greater and resize to %[dim]. The smaller dimension will be resized to preserve aspect ratio. See https://imagemagick.org/script/command- ... p#geometry

You can do unsharp masking and control the arguments. See https://imagemagick.org/script/command- ... hp#unsharp. The sigma can be smaller than 1. So you can go down to about 0.5 before it produces no appreciable change.

Is it possible to add if (w1>h1 and w2<h2 after the trim)
Yes, you can put in conditionals, as a ternary condition. But the results of the condition can only be values or fx arguments such as w or h. You cannot easily make it do different commands. See https://imagemagick.org/script/fx.php. If you can explain what you want mathematically or pseudocode, then perhaps I can clarify further or give you the Imagemagick command.

Re: How to combine 2 images?

Posted: 2018-10-07T03:49:48-07:00
by imanasya
Mathematically I'd like to check before the main magic command if (w1>h1 and w2<h2) after the trim.

If it is true then do

Code: Select all

magick image_0.jpg image_1.jpg -fuzz 2%% -trim +repage -set option:dim "%%[fx:max(max(u.w,v.w),max(u.h,v.h))]" -filter Catrom -resize "%%[dim]x%%[dim]" -unsharp 0x1+0.8+0.05 -background white -gravity center -append -quality 100 combined.jpg
If not true do this:

Code: Select all

magick image_0.jpg -fuzz 2%% -trim +repage -quality 100 first.jpg
I know how to check it (w1>h1 and w2<h2) BEFORE the trim, it will look like this:

Code: Select all

@echo off&setlocal enabledelayedexpansion

for /f "tokens=1,2 delims=:" %%x in ('identify -format %%w:%%h image_0.jpg') do set a/ w1=%%x&set a/ h1=%%y
for /f "tokens=1,2 delims=:" %%x in ('identify -format %%w:%%h image_1.jpg') do set a/ w2=%%x&set a/ h2=%%y

if !h1! LSS !w1!	(		#w1>h1
  if !w2! LSS !h2! (		#w2<h2
  ) else (
  )
)
But I don't know how can I get w1, h1, w2, h2 AFTER the trim.

Re: How to combine 2 images?

Posted: 2018-10-07T03:57:01-07:00
by snibgo
I'm not sure what you are asking. The "for" loops can use "convert" instead of "identify", so can do any processing you want before calculating width and height.

Re: How to combine 2 images?

Posted: 2018-10-07T04:13:23-07:00
by imanasya
snibgo, thank you. Maybe I didn't manage to explain clearly. I use "for" loops for getting values w1, h1, w2, h2 only (parse the strings) , not for the processing. They are original files values. When the trim command ends these values are changing:

Code: Select all

magick image_0.jpg image_1.jpg -fuzz 2%% -trim +repage
And depending on these changed values

Code: Select all

if (w1>h1 & w2<h2)
do this:

Code: Select all

magick image_0.jpg image_1.jpg -fuzz 2%% -trim +repage -set option:dim "%%[fx:max(max(u.w,v.w),max(u.h,v.h))]" -filter Catrom -resize "%%[dim]x%%[dim]" -unsharp 0x1+0.8+0.05 -background white -gravity center -append -quality 100 combined.jpg
else do this:

Code: Select all

magick image_0.jpg -fuzz 2%% -trim +repage -quality 100 first.jpg

Re: How to combine 2 images?

Posted: 2018-10-07T06:38:28-07:00
by snibgo
I can see you don't do any processing in the "for" commands. But you can if you want, and that may help to solve your problem. For example:

Code: Select all

for /f "tokens=1,2 delims=:" %%x in ('convert image_0.jpg -fuzz 2%% -trim +repage -format %%w:%%h +write info: tmp0.png') do set a/ w1=%%x&set a/ h1=%%y