combine.py (3319B)
1 #!/usr/bin/python3 -O 2 3 # combine files in a folder (must be same width) to make images of given height 4 # with margins 5 6 import imageio 7 import collections 8 import sys 9 import numpy 10 import argparse 11 import os.path 12 import os 13 from math import ceil, floor 14 15 parser = argparse.ArgumentParser( 16 description="Split a grayscale PNG image into horizontal strips") 17 parser.add_argument("folder", 18 help="folder for input PNGs (alphabetical order)", type=str) 19 parser.add_argument("output_folder", 20 help="folder to write output files", type=str) 21 parser.add_argument("height", 22 help="height of produced images", type=int) 23 parser.add_argument("--hmargin", 24 help="left and right margins in pixels", 25 type=int, default=10) 26 parser.add_argument("--separator", 27 help="minimal vertical separation between images", 28 type=int, default=10) 29 parser.add_argument("--vmargin", 30 help="top and bottom margins in pixels", 31 type=int, default=10) 32 args = parser.parse_args() 33 34 def make_image(images, names, ofile): 35 global args 36 37 matrix = numpy.full((args.height, 2*args.hmargin+len(images[0][0])), 255, dtype=numpy.uint8) 38 39 #print(list(len(x) for x in images)) 40 #print(len(images)) 41 42 cpos = args.hmargin 43 h = sum(len(x) for x in images) 44 if h + 2*args.vmargin + (len(images)-1)*args.separator > args.height: 45 print("ERROR: image(s) too large: " + " ".join(names)) 46 print("These images were ignored") 47 return None 48 49 if len(images) == 1: 50 # center the image 51 rpos = int(args.vmargin + (args.height - 2*args.vmargin - h)/2) 52 for r in range(len(images[0])): 53 for c in range(len(images[0][0])): 54 matrix[rpos + r][cpos + c] = images[0][r][c] 55 56 else: 57 # multiple images, separate them but do not center 58 # separation per image 59 permargin = int((args.height - 2*args.vmargin - h)/(len(images)-1)) 60 # rounding error 61 offmargin = args.height - 2*args.vmargin - h - permargin*len(images) 62 offset = args.vmargin 63 for i in range(len(images)): 64 for r in range(len(images[i])): 65 for c in range(len(images[i][0])): 66 matrix[r + offset][cpos + c] = images[i][r][c] 67 offset += len(images[i]) 68 offset += permargin 69 if i < offmargin: 70 offset += 1 71 72 imageio.imwrite(ofile, matrix) 73 74 return ofile 75 76 availheight = args.height - 2*args.vmargin 77 78 imgs = [] 79 names = [] 80 totalheight = -args.separator 81 num = 0 82 for f in sorted(os.listdir(args.folder)): 83 img = imageio.imread(os.path.join(args.folder, f)) 84 if len(img) + args.separator + totalheight > availheight: 85 # must finish current batch! 86 outfname = os.path.join(args.output_folder, "out_" + "{:04d}".format(num) + ".png") 87 ret = make_image(imgs, names, outfname) 88 if ret: 89 print("wrote %s into %s" % (",".join(names), ret)) 90 num += 1 91 imgs = [] 92 names = [] 93 totalheight = -args.separator 94 95 totalheight += args.separator + len(img) 96 imgs.append(img) 97 names.append(f) 98 99 if (len(imgs) > 0): 100 # last batch 101 outfname = os.path.join(args.output_folder, "out_" + "{:04d}".format(num) + ".png") 102 make_image(imgs, names, outfname) 103