diff options
| author | Aaron LI <aaronly.me@outlook.com> | 2016-05-08 17:29:17 +0800 | 
|---|---|---|
| committer | Aaron LI <aaronly.me@outlook.com> | 2016-05-08 17:29:17 +0800 | 
| commit | fa68714ac69713f41752572b7b0ef1118edfe383 (patch) | |
| tree | 1c02ec2eda2917fb1398840a7fc92f33d8965513 | |
| parent | b89564d7419df4c81416802496629e63ffb54b66 (diff) | |
| download | cexcess-fa68714ac69713f41752572b7b0ef1118edfe383.tar.bz2 | |
montage_images.py: new; make a montage of the 4 input images
| -rwxr-xr-x | montage_images.py | 90 | 
1 files changed, 90 insertions, 0 deletions
diff --git a/montage_images.py b/montage_images.py new file mode 100755 index 0000000..95cf390 --- /dev/null +++ b/montage_images.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python3 +# +# Aaron LI +# Created: 2016-05-08 +# Updated: 2016-05-08 +# + +""" +Make a montage of the input 4 images by utilizing the `montage` +tool from `ImageMagick`. + +Montage: ++----------+----------+ +|          |          | +|  image1  |  image2  | +|          |          | ++----------+----------+ +|          |          | +|  image3  |  image4  | +|          |          | ++----------+----------+ + +Note: +The resolution/dimension of the `image1` is taken as the reference, and +the other 3 images are re-sized to match it in order to make an compact +and grid-aligned montage. + + +Credits: +[1] ImageMagick v6 Examples -- Montage, Arrays of Images +    https://www.imagemagick.org/Usage/montage/ +[2] ImageMagick montage: Resizing only one input image +    https://stackoverflow.com/a/26273173/4856091 +""" + + +import subprocess +import argparse + + +def get_image_size(image): +    """ +    Get the size (dimension) of the image by utilizing `identify`. +    """ +    results = subprocess.run(["identify", "-ping", "-format", "%w %h", image], +                             check=True, stdout=subprocess.PIPE) +    width, height = map(int, results.stdout.decode("utf-8").split()) +    return (width, height) + + +def montage_images(infiles, outfile): +    """ +    Combine the 4 input images to make a montage by utilizing `montage`. +    """ +    img1, img2, img3, img4 = infiles +    # `img1` is taken as the reference image (top-left) +    w_ref, h_ref = get_image_size(img1) +    w_img2, h_img2 = get_image_size(img2) +    w_img3, h_img3 = get_image_size(img3) +    # `img2` is re-sized to have the same height as `img1` (top-right) +    ratio_img2 = h_ref / h_img2 +    W_img2, H_img2 = int(w_img2*ratio_img2), int(h_img2*ratio_img2) +    # `img3` is re-sized to match the width of `img1` (bottom-left) +    ratio_img3 = w_ref / w_img3 +    W_img3, H_img3 = int(w_img3*ratio_img3), int(h_img3*ratio_img3) +    # `img4` is simply re-sized to fill the bottom-right area +    W_img4, H_img4 = W_img2, H_img3 +    subprocess.run(args=[ +        "montage", img1, +        "(", img2, "-resize", "%dx%d" % (W_img2, H_img2), ")", +        "(", img3, "-resize", "%dx%d" % (W_img3, H_img3), ")", +        "(", img4, "-resize", "%dx%d" % (W_img4, H_img4), ")", +        "-geometry", "+1+1", "-tile", "2x2", outfile, +    ]) + + +def main(): +    parser = argparse.ArgumentParser( +        description="Make a montage of the input 4 images") +    parser.add_argument("-o", "--outfile", dest="outfile", required=True, +                        help="output filename of the montage image") +    parser.add_argument("images", nargs=4, +                        help="filenames of 4 input images") +    args = parser.parse_args() + +    montage_images(infiles=args.images, outfile=args.outfile) + + +if __name__ == "__main__": +    main()  | 
