# build an array of images to use in the gif
my @images;
# synthesize the images or read them from files, it doesn't matter
...
# write the gif
Imager->write_multi({ file=>$filename, type=>'gif' }, @images)
or die Imager->errstr;

The main issue that can occur with this is if the input file has transparency and the output file format doesn't support that. This can be a problem when converting from GIF files to JPEG files for example.

By default, if the output format doesn't support transparency, Imager will compose the image onto a black background. You can override that by supplying an i_background option to write() or write_multi():

WARNING: file format attacks have become a common attack vector, make sure you have up to date image file format libraries, otherwise trying to parse uploaded files, whether with Imager or some other tool, may result in a remote attacker being able to run their own code on your system.

If your HTML form uses the correct magic, it can upload files to your CGI script, in particular, you need to use method="post" and enctype="multipart/form-data" in the form tag, and use type="file" in the input, for example:

Whether you draw the border before or after pasting the original image depends on whether you want the border to overlap the image, for example a semi-transparent border drawn after pasting the source image could overlap the edge without hiding it.

If you want a solid border you could just fill the image before pasting the source for simplicity:

Most image file formats store information about the physical size of the pixels, though in some cases that information isn't useful.

Imager stores this information in the tags i_xres and i_yres, and this is always stored in dots per inch.

Some formats, including TIFF and JPEG allow you to change the units spatial resolution information is stored in, if you set the tag that changes this the Imager will convert i_xres and i_yres to those units when it writes the file.