I'm installing a remote network of spherical/360-degree cameras and need to have the images they produce all aligned with something (north). The problem is, the cameras might end up being mounted facing any random direction, so I need to shift/offset (horizontally) the image, and wrap whatever ends up outside the bounds of the image to the other side.
After taking a sample image after installation of each camera, I will know the correct pixel value to offset the image and will be able to specify the offset value on a per-camera basis.
The first half of this article explains how to do this in Photoshop (Filter menu > Other > Offset, specify an offset pixel value, and then enable the "wrap around" option). Photoshop offsets the image by the defined number of pixels, and any excess is automatically moved to the other side of the image to fill in the gap created by shifting the image.
I just need to automate the offsetting of the image and wrap the excess around to the other side of the image so that no part of the image is actually lost, in a Linux (Raspbian) environment, via the command line. I am not able to use a GUI to do this as we're talking about millions of images in the long-term.
I tried doing this with Imagemagick's geometry offset tool (convert -geometry +0+100 R0011996.JPG
), but a) I couldn't figure out how to actually use it, and b) there doesn't seem to be an option like the "wrap around" option in Photoshop.
I just realised The GIMP has an equivalent tool and a command-line interface and tried that, but couldn't find any decent documentation. I found the Procedure Browser, which said to use "gimp-drawable-offset". I tried the following, but it failed:
gimp -i -b '(gimp-drawable-offset "R0011996.JPG" 1 2 300 0)' -b '(set! drawable (car (gimp-image-get-active-layer image)))' -b '(gimp-quit 0)'
batch command experienced an execution error: Error: Invalid type for argument 1 to gimp-drawable-offset
batch command experienced an execution error: Error: eval: unbound variable: image
and
gimp -i -b '(gimp-drawable-offset 1 2 300 0)' -b '(set! drawable (car (gimp-image-get-active-layer "R0011996.JPG")))' -b '(gimp-quit 0)'
batch command experienced an execution error: Error: Invalid number of arguments for gimp-drawable-offset (expected 5 but received 4)
batch command experienced an execution error: Error: Invalid type for argument 1 to gimp-image-get-active-layer
and...
gimp -i -b '(gimp-drawable-offset "R0011996.JPG" TRUE 2 300 0)' -b '(set! drawable (car (gimp-image-get-active-layer image)))' -b '(gimp-quit 0)'
batch command experienced an execution error: Error: Invalid type for argument 1 to gimp-drawable-offset
batch command experienced an execution error: Error: eval: unbound variable: image
...and...
gimp -i -b '(gimp-drawable-offset "R0011996.JPG" TRUE 2 300 0)' -b '(set! drawable (car (gimp-image-get-active-layer "R0011996.JPG")))' -b '(gimp-quit 0)'
batch command experienced an execution error: Error: Invalid type for argument 1 to gimp-drawable-offset
batch command experienced an execution error: Error: Invalid type for argument 1 to gimp-image-get-active-layer
Any suggestions please on how to achieve this?
Thanks in advance.
Thanks to Xenoid, who answered in a comment. The solution is simple:
convert input.jpg -roll +400+0 output.jpg
Where 400 is the x shift in pixels and 0 is the y shift in pixels (you can also use negative values to reverse the directions of the shifts if desired). Refer to the section "Rolling Images like a bad TV" here.