Search code examples
javascriptnode.jsimagemagickgraphicsmagick

Add margin between appended images with GraphicsMagick/gm


Using the gm package for Node, I can append three images horizontally:

gm('img1.jpg').append('img2.jpg', true).append('img3.jpg', true).write('out.jpg');

This creates something like:

+---+---+---+
| 1 | 2 | 3 |
+---+---+---+

Where all the images touch. However, I want 10px of margin, so it looks like this:

+---+  +---+  +---+
| 1 |  | 2 |  | 3 |
+---+  +---+  +---+

I could do this by creating a strip image, and appending it after each one, but this seems rather hacky. Any ideas?


Solution

  • I don't really do Javascript, or node, but I can say that on the command line, I would tend to do what you ask with the montage command, but it can be done with convert. What you need to know, and what may be useful, is that you don't have to create a spacer file in the filesystem and put that under configuration control and into build scripts etc - rather, you can create on dynamically.

    So, if I have three images each 50x50 pixels as follows:

    red.png

    enter image description here

    green.png

    enter image description here

    blue.png

    enter image description here

    If you append them as you say, you will do this

    convert red.png green.png blue.png +append result.png
    

    giving this

    enter image description here

    If you want them spaced by 10 pixels, you can preset that size just once, and then dynamically create one or more spacers, without the need for anything in the filesystem, like this, where xc:none is a little piece of transparent canvas:

    convert -size 10x red.png xc:none green.png xc:none blue.png +append result.png
    

    enter image description here

    If you want to understand better how it works, I have changed some parameters so you can see where the transparent, pink and yellow parts are coming from and adapt them to you needs:

    convert -background pink -size 80x20 red.png xc:none green.png xc:yellow blue.png +append montage.png
    

    enter image description here

    Another Option

    There is another way of doing what you want, that is by splicing some extra background onto your images before you append them, like this:

    convert -gravity east -background yellow red.png blue.png -splice 90x green.png +append montage.png
    

    enter image description here

    Notice that I have set the gravity to East so the extra columns get appended on the right side of each image, and also that I only spliced once - the reason is that -splice is an operator and hence it applies to all images already loaded (i.e. red.png and blue.png), whereas -gravity east and -background yellow are settings which persist till the end of the command, or changed.