Variable margins based on page number

This commit is contained in:
Marco van Dijk 2021-07-27 14:48:57 +02:00
parent 9992b7ac36
commit 568054b986
4 changed files with 41 additions and 25 deletions

View File

@ -30,7 +30,7 @@ def initConfig():
# Else load defaults # Else load defaults
else: else:
config['input'] = {'inputFolders': os.getcwd(), config['input'] = {'inputFolders': os.getcwd(),
'maxDepth': 2, 'maxDepth': 1,
'readtxt': 1, 'readtxt': 1,
'readraw': 1 'readraw': 1
} }
@ -46,9 +46,9 @@ def initConfig():
'backgroundColour': '255,255,255', 'backgroundColour': '255,255,255',
'fontColour': '0,0,0', 'fontColour': '0,0,0',
'metadataColour': '128,128,128', 'metadataColour': '128,128,128',
'topMargin': 50, 'verticalMargin': 50,
'leftMargin': 100, 'horizontalMargin': 100,
'rightMargin': 50, 'extraHorizontalMargin': 100,
'tryToShrinkRatio' : 0.4, 'tryToShrinkRatio' : 0.4,
'lowestwhitespaceonwidthratioallowed': 0.90, 'lowestwhitespaceonwidthratioallowed': 0.90,
'highestwhitespaceonwidthratioallowed': 0.40, 'highestwhitespaceonwidthratioallowed': 0.40,

View File

@ -203,7 +203,9 @@ class Song:
# Flag for succesfully parsed # Flag for succesfully parsed
self.isParsed = False self.isParsed = False
configObj = lib.config.config['output'] configObj = lib.config.config['output']
self.topMargin = int(configObj['topMargin']) self.verticalMargin = int(configObj['verticalMargin'])
self.horizontalMargin = int(configObj['horizontalMargin'])
self.extraHorizontalMargin = int(configObj['extraHorizontalMargin'])
self.fontColour = tuple(int(var) for var in configObj['fontColour'].split(',')) self.fontColour = tuple(int(var) for var in configObj['fontColour'].split(','))
self.backgroundColour = tuple(int(var) for var in configObj['backgroundColour'].split(',')) self.backgroundColour = tuple(int(var) for var in configObj['backgroundColour'].split(','))
self.metadataColour = tuple(int(var) for var in configObj['metadataColour'].split(',')) self.metadataColour = tuple(int(var) for var in configObj['metadataColour'].split(','))
@ -215,8 +217,6 @@ class Song:
# Since font size is then shrunk and grown to fit whitespace we do not need to be as accurate # Since font size is then shrunk and grown to fit whitespace we do not need to be as accurate
# PPI of 144 -> fontSize of 32 # PPI of 144 -> fontSize of 32
self.fontSize = int(self.ppi / 4.5) self.fontSize = int(self.ppi / 4.5)
self.leftMargin = int(configObj['leftMargin'])
self.rightMargin = int(configObj['rightMargin'])
self.fontLyrics = ImageFont.truetype(configObj['lyricfontfamily'], self.fontSize) self.fontLyrics = ImageFont.truetype(configObj['lyricfontfamily'], self.fontSize)
self.fontTablature = ImageFont.truetype(configObj['tablaturefontfamliy'], self.fontSize) self.fontTablature = ImageFont.truetype(configObj['tablaturefontfamliy'], self.fontSize)
self.fontFamilyLyrics = configObj['lyricfontfamily'] self.fontFamilyLyrics = configObj['lyricfontfamily']
@ -248,7 +248,7 @@ class Song:
""" """
def calculateMetadataDimensions(self): def calculateMetadataDimensions(self):
# metadata starts topMargin removed from top # metadata starts topMargin removed from top
currentHeight = self.topMargin currentHeight = self.verticalMargin
maxWidth = 0 maxWidth = 0
for line in self.metadata.split('\n'): for line in self.metadata.split('\n'):
line = line.rstrip() line = line.rstrip()
@ -308,8 +308,8 @@ class Song:
""" """
def checkOverflowX(self): def checkOverflowX(self):
for section in self.sections: for section in self.sections:
if section.expectedWidth > self.imageWidth - self.leftMargin - self.rightMargin: if section.expectedWidth > self.imageWidth - self.extraHorizontalMargin - self.horizontalMargin - self.horizontalMargin:
print("There is an overflow on width: this section has a width of {}, but we have {} ({}-{}-{}) amount of space".format(section.expectedWidth, self.imageWidth - self.leftMargin - self.rightMargin, self.imageWidth, self.leftMargin, self.rightMargin)) print("There is an overflow on width: this section has a width of {}, but we have {} ({}-{}-{}*2) amount of space".format(section.expectedWidth, self.imageWidth - self.extraHorizontalMargin - self.horizontalMargin - self.horizontalMargin, self.imageWidth, self.extraHorizontalMargin, self.horizontalMargin))
return False return False
return True return True
@ -317,7 +317,7 @@ class Song:
@return True if everything OK, False if overflowing @return True if everything OK, False if overflowing
""" """
def checkOverflowMetadata(self): def checkOverflowMetadata(self):
if self.metadataWidth > self.imageWidth - self.leftMargin - self.rightMargin: if self.metadataWidth > self.imageWidth - self.extraHorizontalMargin - self.horizontalMargin - self.horizontalMargin:
return False return False
return True return True
@ -331,7 +331,7 @@ class Song:
self.resizeAllSections(+1) self.resizeAllSections(+1)
self.sectionsToPages() self.sectionsToPages()
currentPageAmount = len(self.pages) currentPageAmount = len(self.pages)
# Increase fontSize as long as we do not add a page # Increase fontSize as long as we stay under the target max pages
while ((currentPageAmount <= targetPageAmount) and self.checkOverflowX()): while ((currentPageAmount <= targetPageAmount) and self.checkOverflowX()):
self.resizeAllSections(+1) self.resizeAllSections(+1)
self.sectionsToPages() self.sectionsToPages()
@ -362,7 +362,8 @@ class Song:
biggestWhitespace = -1 biggestWhitespace = -1
for page in self.pages: for page in self.pages:
for section in page.sections: for section in page.sections:
whitespaceOnWidth = self.imageWidth - self.leftMargin - self.rightMargin - section.expectedWidth # We have 2* horizontal whitespace
whitespaceOnWidth = self.imageWidth - self.extraHorizontalMargin - self.horizontalMargin - self.horizontalMargin - section.expectedWidth
if whitespaceOnWidth < smallestWhitespace: if whitespaceOnWidth < smallestWhitespace:
smallestWhitespace = whitespaceOnWidth smallestWhitespace = whitespaceOnWidth
if whitespaceOnWidth > biggestWhitespace: if whitespaceOnWidth > biggestWhitespace:
@ -398,13 +399,13 @@ class Song:
""" """
def sectionsToPages(self): def sectionsToPages(self):
# If we are keeping whitespace, don't count the whitespace in between sections # If we are keeping whitespace, don't count the whitespace in between sections
sectionWhitespace = self.topMargin sectionWhitespace = self.verticalMargin
if self.keepEmptyLines: if self.keepEmptyLines:
sectionWhitespace = 0 sectionWhitespace = 0
self.prerenderSections() self.prerenderSections()
self.pages = [] self.pages = []
# First page contains metadata # First page contains metadata
currentHeight = self.topMargin currentHeight = self.verticalMargin
currentHeight += self.metadataHeight currentHeight += self.metadataHeight
currentHeight += sectionWhitespace currentHeight += sectionWhitespace
curPage = Page() curPage = Page()

View File

@ -75,8 +75,12 @@ def main():
# Prerender: calculate Pages, and move sections into Pages # Prerender: calculate Pages, and move sections into Pages
song.sectionsToPages() song.sectionsToPages()
# Optimalisation: try to fill whitespace # Optimalisation: try to fill whitespace
while song.canFillWhitespace() or len(song.pages) > song.maxPages: while len(song.pages) > song.maxPages:
print("Resizing down to fit whitespace more efficiently") print("Resizing down since we have {} pages and want {} pages".format(len(song.pages), song.maxPages))
song.resizeAllSections(-1)
song.sectionsToPages()
while song.canFillWhitespace():
print("Resizing down to fill remaining vertical whitespace")
song.resizeAllSections(-1) song.resizeAllSections(-1)
song.sectionsToPages() song.sectionsToPages()
# Optimalisation: increase font size to fit target page amount # Optimalisation: increase font size to fit target page amount

View File

@ -36,12 +36,18 @@ def outputToImage(folderLocation, songObj):
# Init image info # Init image info
imageNumber = 1 imageNumber = 1
currentHeight = songObj.topMargin currentHeight = songObj.verticalMargin
# New Image # New Image
a4image = Image.new('RGB',(songObj.imageWidth, songObj.imageHeight),(songObj.backgroundColour)) a4image = Image.new('RGB',(songObj.imageWidth, songObj.imageHeight),(songObj.backgroundColour))
draw = ImageDraw.Draw(a4image) draw = ImageDraw.Draw(a4image)
# Add extra whitespace on the left if this is an even page
# The whitespace on the right for uneven pages is handled elsewhere, by limiting the maximum horizontal size
horizontalMargin = songObj.horizontalMargin
if (imageNumber % 2) == 0:
horizontalMargin += songObj.extraHorizontalMargin
# Write metadata # Write metadata
for line in songObj.metadata.split('\n'): for line in songObj.metadata.split('\n'):
# remove any unwanted characters from metadata # remove any unwanted characters from metadata
@ -50,12 +56,12 @@ def outputToImage(folderLocation, songObj):
continue continue
#print("meta line '{}'".format(line)) #print("meta line '{}'".format(line))
metadataTextWidth, metadataTextHeight = songObj.fontMetadata.getsize(line) metadataTextWidth, metadataTextHeight = songObj.fontMetadata.getsize(line)
draw.text((songObj.leftMargin,currentHeight), line, fill=songObj.metadataColour, font=songObj.fontMetadata) draw.text((horizontalMargin, currentHeight), line, fill=songObj.metadataColour, font=songObj.fontMetadata)
currentHeight += metadataTextHeight currentHeight += metadataTextHeight
# Draw all pages # Draw all pages
for page in songObj.pages: for page in songObj.pages:
# Margin between metadata and the first section / section and top of page # Margin between metadata and the first section / section and top of page
currentHeight += songObj.topMargin currentHeight += songObj.verticalMargin
for section in page.sections: for section in page.sections:
# Reset section specific variables # Reset section specific variables
lineIterator = 0 lineIterator = 0
@ -68,7 +74,7 @@ def outputToImage(folderLocation, songObj):
return return
# write section title # write section title
headerWidth, headerHeight = songObj.fontTablature.getsize(section.header) headerWidth, headerHeight = songObj.fontTablature.getsize(section.header)
draw.text((songObj.leftMargin,currentHeight), section.header, fill=songObj.fontColour, font=songObj.fontTablature) draw.text((horizontalMargin ,currentHeight), section.header, fill=songObj.fontColour, font=songObj.fontTablature)
currentHeight += headerHeight currentHeight += headerHeight
# Write each line tablature&lyric data # Write each line tablature&lyric data
while lineIterator < amountOfLines: while lineIterator < amountOfLines:
@ -77,22 +83,27 @@ def outputToImage(folderLocation, songObj):
lyricTextWidth, lyricTextHeight = songObj.fontLyrics.getsize(section.lyrics[lineIterator]) lyricTextWidth, lyricTextHeight = songObj.fontLyrics.getsize(section.lyrics[lineIterator])
tablatureTextWidth, tablatureTextHeight = songObj.fontTablature.getsize(section.tablatures[lineIterator]) tablatureTextWidth, tablatureTextHeight = songObj.fontTablature.getsize(section.tablatures[lineIterator])
# add to image file # add to image file
draw.text((songObj.leftMargin,currentHeight), section.tablatures[lineIterator], fill=songObj.fontColour, font=songObj.fontTablature) draw.text((horizontalMargin ,currentHeight), section.tablatures[lineIterator], fill=songObj.fontColour, font=songObj.fontTablature)
currentHeight += tablatureTextHeight currentHeight += tablatureTextHeight
draw.text((songObj.leftMargin,currentHeight), section.lyrics[lineIterator], fill=songObj.fontColour, font=songObj.fontLyrics) draw.text((horizontalMargin ,currentHeight), section.lyrics[lineIterator], fill=songObj.fontColour, font=songObj.fontLyrics)
currentHeight += lyricTextHeight currentHeight += lyricTextHeight
lineIterator += 1 lineIterator += 1
#print("currentheight={}".format(currentHeight)) #print("currentheight={}".format(currentHeight))
# If we stripped al whitespace, we need to add whitespace between sections # If we stripped al whitespace, we need to add whitespace between sections
if not songObj.keepEmptyLines: if not songObj.keepEmptyLines:
currentHeight += songObj.topMargin currentHeight += songObj.verticalMargin
# Got all sections in the page, so write it # Got all sections in the page, so write it
outputLocation = folderLocation + "/" + songObj.title + '-' + str(imageNumber) + ".png" outputLocation = folderLocation + "/" + songObj.title + '-' + str(imageNumber) + ".png"
a4image.save(outputLocation) a4image.save(outputLocation)
a4image = Image.new('RGB',(songObj.imageWidth, songObj.imageHeight),(songObj.backgroundColour)) a4image = Image.new('RGB',(songObj.imageWidth, songObj.imageHeight),(songObj.backgroundColour))
draw = ImageDraw.Draw(a4image) draw = ImageDraw.Draw(a4image)
currentHeight = songObj.topMargin currentHeight = songObj.verticalMargin
imageNumber += 1 imageNumber += 1
# Add extra whitespace on the left if this is an even page
# The whitespace on the right for uneven pages is handled elsewhere, by limiting the maximum horizontal size
horizontalMargin = songObj.horizontalMargin
if (imageNumber % 2) == 0:
horizontalMargin += songObj.extraHorizontalMargin