Layering with different geometry
Layering with different geometry
I have: convert a.gif b.gif c.gif e.gif g.gif z.gif +append append.png
convert a.gif b.gif c.gif e.gif g.gif z.gif -geometry south +append append.png => will apply geometry south to all images
I want to apply different geometries on different images, how can I accomplish that?
I want a b c z with "south", but g with "north" geometry.
convert a.gif b.gif c.gif e.gif g.gif z.gif -geometry south +append append.png => will apply geometry south to all images
I want to apply different geometries on different images, how can I accomplish that?
I want a b c z with "south", but g with "north" geometry.
- fmw42
- Posts: 25562
- Joined: 2007-07-02T17:14:51-07:00
- Authentication code: 1152
- Location: Sunnyvale, California, USA
Re: Layering with different geometry
You will have to append them one at a time to build up the final image.
Or use
-page ... -mosaic
or
-gravity ... -compose over -composite
to composite them all at the correct locations.
see
http://www.imagemagick.org/Usage/layers/#convert
http://www.imagemagick.org/Usage/layers/#mosaic
Or use
-page ... -mosaic
or
-gravity ... -compose over -composite
to composite them all at the correct locations.
see
http://www.imagemagick.org/Usage/layers/#convert
http://www.imagemagick.org/Usage/layers/#mosaic
Re: Layering with different geometry
Thanks Fred.
What's the fastest way out of these (in processing time)?
What's the fastest way out of these (in processing time)?
- fmw42
- Posts: 25562
- Joined: 2007-07-02T17:14:51-07:00
- Authentication code: 1152
- Location: Sunnyvale, California, USA
Re: Layering with different geometry
It is not really a question of speed, but convenience.
Doing multiple appends is not really helpful unless you can script a loop over all your images and save each append.
Using -mosaic, does not need to have a background image, but you have to use -page relative to the upper left corner of your desired output but you can specify all images with one -mosaic.
Using -compose over with -gravity and -geometry is the easiest, but you have to do the composite for each image and you must build your background image. However, you can build it as big as you want and then use -trim at the end to cut out excess.
If you are on Linux, Mac, you could use pipes to do the append in one command line.
convert image1 image2 -gravity ... +append miff:- | convert - image3 -gravity ... +append miff:- | ... | convert - imageN -gravity ... +append output
I do not know if Windows supports piping, but you can try if you are on Windows.
Doing multiple appends is not really helpful unless you can script a loop over all your images and save each append.
Using -mosaic, does not need to have a background image, but you have to use -page relative to the upper left corner of your desired output but you can specify all images with one -mosaic.
Using -compose over with -gravity and -geometry is the easiest, but you have to do the composite for each image and you must build your background image. However, you can build it as big as you want and then use -trim at the end to cut out excess.
If you are on Linux, Mac, you could use pipes to do the append in one command line.
convert image1 image2 -gravity ... +append miff:- | convert - image3 -gravity ... +append miff:- | ... | convert - imageN -gravity ... +append output
I do not know if Windows supports piping, but you can try if you are on Windows.
- anthony
- Posts: 8883
- Joined: 2004-05-31T19:27:03-07:00
- Authentication code: 8675308
- Location: Brisbane, Australia
Re: Layering with different geometry
First... it is gravity not geometry.
Second... Layering is the major alturnative allowing you to position images by seting the 'virtual canavs offset' (known for hisorically reasons as 'page').
For example... setting the location of 12 'rose' images (or however many you want!)
This uses the image index 't' divided by the number of images 'n' to calculate an angle in radians. that is used to then position the image in a circle using sin() and cos() and radius 100, setting the offset to the top-left corner of the image using -set page. The -layers merge then merges the images relative to each other regardless of if the offsets are positive or negative, and the +repage removes any resulting negative offset.
Hmmm.. that is probably one of the BEST examples of programmed positioning I have yet seen!
And I just thought it up on the spot.
I have to put a simular this in IM Examples, Layering. (to appear in a few hours)
http://www.imagemagick.org/Usage/layers/#layer_calc
This just proves that my effort to ensure that 't' image indexing works was a good idea and just how useful it is. The same goes for having a '-layers merge' operation that does not care whether offsets are positive or negative.
Warning, while the above example does not show it. the last image (just above the right-most image) will always be on top of all the rest, to make a true cyclic overlap you would probably have to generate the image twice so that you can set the last image over the second last, but under the first (zeroth) image. That would really be tricky!
Second... Layering is the major alturnative allowing you to position images by seting the 'virtual canavs offset' (known for hisorically reasons as 'page').
For example... setting the location of 12 'rose' images (or however many you want!)
Code: Select all
convert rose: -duplicate 11 \
-set page '+%[fx:100*cos((t/n)*2*pi)]+%[fx:100*sin((t/n)*2*pi)]' \
-layers merge +repage rose_circle.png
This uses the image index 't' divided by the number of images 'n' to calculate an angle in radians. that is used to then position the image in a circle using sin() and cos() and radius 100, setting the offset to the top-left corner of the image using -set page. The -layers merge then merges the images relative to each other regardless of if the offsets are positive or negative, and the +repage removes any resulting negative offset.
Hmmm.. that is probably one of the BEST examples of programmed positioning I have yet seen!
And I just thought it up on the spot.
I have to put a simular this in IM Examples, Layering. (to appear in a few hours)
http://www.imagemagick.org/Usage/layers/#layer_calc
This just proves that my effort to ensure that 't' image indexing works was a good idea and just how useful it is. The same goes for having a '-layers merge' operation that does not care whether offsets are positive or negative.
Warning, while the above example does not show it. the last image (just above the right-most image) will always be on top of all the rest, to make a true cyclic overlap you would probably have to generate the image twice so that you can set the last image over the second last, but under the first (zeroth) image. That would really be tricky!
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
https://imagemagick.org/Usage/
-
- Posts: 12159
- Joined: 2010-01-23T23:01:33-07:00
- Authentication code: 1151
- Location: England, UK
Re: Layering with different geometry
Not too tricky. Windows script:
Code: Select all
"%IMG6846%convert" ^
rose: ^
-duplicate 11 ^
-set page "+%%[fx:75*cos((t/n)*2*pi)]+%%[fx:75*sin((t/n)*2*pi)]" ^
( -clone 0 -set page +0+0 -crop 100%%x50%%+0+0 -set page +75+0 ) ^
-layers merge +repage ^
rose_circle.png
snibgo's IM pages: im.snibgo.com
- anthony
- Posts: 8883
- Joined: 2004-05-31T19:27:03-07:00
- Authentication code: 8675308
- Location: Brisbane, Australia
Re: Layering with different geometry
With the power of IM doing the work behind it ... very simple!
Before the ability to use 't' in FX expressions (fixed in IM v6.6.8-10, 27 March 2011) you needed to use what I am now calling a two-staged, streaming images approach, so you can do position calculations outside IM
See IM Examples, Programmed Positioning of Images
http://www.imagemagick.org/Usage/layers/#layer_prog
It was quite complex, and probably very hard to translate to Windows.
The previous example of using 't' was
Animated Distorts - distorting multiple image based on image index
http://www.imagemagick.org/Usage/anim_mods/#distort
This new example is much better and far more dramatic.
Before the ability to use 't' in FX expressions (fixed in IM v6.6.8-10, 27 March 2011) you needed to use what I am now calling a two-staged, streaming images approach, so you can do position calculations outside IM
See IM Examples, Programmed Positioning of Images
http://www.imagemagick.org/Usage/layers/#layer_prog
It was quite complex, and probably very hard to translate to Windows.
The previous example of using 't' was
Animated Distorts - distorting multiple image based on image index
http://www.imagemagick.org/Usage/anim_mods/#distort
This new example is much better and far more dramatic.
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
https://imagemagick.org/Usage/
- anthony
- Posts: 8883
- Joined: 2004-05-31T19:27:03-07:00
- Authentication code: 8675308
- Location: Brisbane, Australia
Re: Layering with different geometry
Note this 'calculated' method is not good for generating the equivelent of an Append, as in that case the position depends on the position and width of every other image before it.
However in fixing the 't' and 'n' FX Expressions, I also allowed FX expressions to be able to access 'image attributes' from any other images in the list, including the images before it. What attributes it has access to is currently limited, but it is posible to craete a DIY append...
Hmmm, First looking at using the attribuets of the previous image...
Well it worked, but the result is not right... the 'image' width is always 20! That is the first images 'w' value!
Oh okay a s[image_index] is not relative to the current image 's' but to the start of the list! okay.
Attempt two...
that worked! though the image -1 (from t-1 for the first (zero index) image above) should be the 'last' image (image index -1) still gets the value from the first image -- that is a bug!
So lets try setting the page to the previous images 'x' offset plus that images with, setting that images x offset
YES! replace info: with -layers merge and you have a DIY append
(using relative position, and not calculating the exact position due to first image handling)
Lesson: When using a image index, whether the image is u,v, or s does not matter! You much use 't' to specify a relative image index.
BUG: u[-1] is accessing the first image, not the last image as it is supposed to according to documentation.
Getting back to the OP. now that you have an programmed append, you can adjust the 'Y' offset, as you like. Of course finding the 'maximum height' of all the images in the one command is still a problem, but one that could be solved by generating a intermediate image that discovered the maximum height of all the images. Perhaps though more 'incremental' settings, and multiple setting runs.
Hmmmm get the maximum height!
So just set all image to that maximum offset, then reset all images but e.gif image ( image index 4, counting from zero) to 0, and set that image to the hight adjusted offset. You can then do the DIY append (preserving the vertical offset (using '%Y' instead of '%[fx:page.y]'
This works, and is VERY fast, except for the first (zero image) see below...
Note the last step could be combined with the second last.
PS: the above works, but seems to go wrong for image index 0. As did not set the value into the first image. Again I don't know why.
In a similar way instead of using I would have thought I could assign it directly using but all images except the last gets a value of zero!
This is all new territory and as such I am certain we are finding some new bugs.
However in fixing the 't' and 'n' FX Expressions, I also allowed FX expressions to be able to access 'image attributes' from any other images in the list, including the images before it. What attributes it has access to is currently limited, but it is posible to craete a DIY append...
Hmmm, First looking at using the attribuets of the previous image...
Code: Select all
convert -size 20x10 xc:red -size 50x10 xc:green -size 30x10 xc:blue \
+repage -set page ']+%[fx:s[-1].w]' \
info:
xc:red[0] XC 20x10 0x0+20+0 16-bit sRGB 0.000u 0:00.219
xc:green[1] XC 50x10 0x0+20+0 16-bit sRGB 0.000u 0:00.080
xc:blue[2] XC 30x10 0x0+20+0 16-bit sRGB 0.000u 0:00.080
Oh okay a s[image_index] is not relative to the current image 's' but to the start of the list! okay.
Attempt two...
Code: Select all
convert -size 20x10 xc:red -size 50x10 xc:green -size 30x10 xc:blue \
+repage -set page '+%[fx:s[t-1].w]' \
info:
xc:red[0] XC 20x10 0x0+20+0 16-bit sRGB 0.000u 0:00.009
xc:green[1] XC 50x10 0x0+20+0 16-bit sRGB 0.000u 0:00.009
xc:blue[2] XC 30x10 0x0+50+0 16-bit sRGB 0.000u 0:00.009
So lets try setting the page to the previous images 'x' offset plus that images with, setting that images x offset
Code: Select all
convert -size 20x10 xc:red -size 50x10 xc:green -size 30x10 xc:blue \
+repage -set page '+%[fx:s[t-1]page.x+s[t-1].w]+0' \
info:
xc:red[0] XC 20x10 0x0+20+0 16-bit sRGB 0.000u 0:00.010
xc:green[1] XC 50x10 0x0+40+0 16-bit sRGB 0.000u 0:00.000
xc:blue[2] XC 30x10 0x0+90+0 16-bit sRGB 0.000u 0:00.000
(using relative position, and not calculating the exact position due to first image handling)
Code: Select all
convert rose: netscape: granite: \
+repage -set page '+%[fx:u[t-1]page.x+u[t-1].w]+0' \
-background DodgerBlue -layers merge +repage show:
BUG: u[-1] is accessing the first image, not the last image as it is supposed to according to documentation.
Getting back to the OP. now that you have an programmed append, you can adjust the 'Y' offset, as you like. Of course finding the 'maximum height' of all the images in the one command is still a problem, but one that could be solved by generating a intermediate image that discovered the maximum height of all the images. Perhaps though more 'incremental' settings, and multiple setting runs.
Hmmmm get the maximum height!
Code: Select all
convert rose: netscape: granite: \
-set page '+0+%[fx:max(u[t-1].h,s.h)]' \
-set option:my:max_height '%[fx:u[n-1].page.y]' \
-format '%[my:max_height]\n' info:
Code: Select all
convert a.gif b.gif c.gif d.gif.e.gif z.gif \
-set page '+0+%[fx:max(u[t-1].h,s.h)]' \
-set option:my:max_height '%[fx:u[n-1].page.y]' \
-set page '+0+%[my:max_height]' \
-set page '+0+%[fx:t==4?page.y-h:0]' \
-set page '+%[fx:u[t-1]page.x+u[t-1].w]+%Y' \
-background DodgerBlue -layers merge +repage show:
Note the last step could be combined with the second last.
PS: the above works, but seems to go wrong for image index 0. As
Code: Select all
-set page '+0+%[my:max_height]'
In a similar way instead of using
Code: Select all
-set option:my:max_height '%[fx:u[n-1].page.y]' \
-set page '+0+%[my:max_height]'
Code: Select all
-set page '+0+%[fx:u[n-1].page.y]'
This is all new territory and as such I am certain we are finding some new bugs.
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
https://imagemagick.org/Usage/
- anthony
- Posts: 8883
- Joined: 2004-05-31T19:27:03-07:00
- Authentication code: 8675308
- Location: Brisbane, Australia
Re: Layering with different geometry
This ability to access attributes of other images, also includes the pixel data of other images.
That means you could position a list of images according to say values found in the first (or last) image in the list, though that 'mapping' image would also be re-positioned.
How useful 'mapped positions' would be is another matter. It is just another possibility
That means you could position a list of images according to say values found in the first (or last) image in the list, though that 'mapping' image would also be re-positioned.
How useful 'mapped positions' would be is another matter. It is just another possibility
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
https://imagemagick.org/Usage/