songflower

reflow bitmap sheet music to a different paper format
git clone https://a3nm.net/git/songflower/
Log | Files | Refs | README | LICENSE

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