Compare commits
2 Commits
a30d678c08
...
b6309cf16c
Author | SHA1 | Date | |
---|---|---|---|
b6309cf16c | |||
27fdf3cf24 |
11
.gitignore
vendored
11
.gitignore
vendored
@ -1,7 +1,10 @@
|
||||
**/__pycache__
|
||||
.vscode
|
||||
.venv
|
||||
|
||||
recordings/
|
||||
*.mkv
|
||||
*.png
|
||||
out/
|
||||
|
||||
.venv
|
||||
mscz/
|
||||
recordings/
|
||||
**/__pycache__
|
||||
scores
|
@ -1,86 +1,25 @@
|
||||
from xml.etree import ElementTree
|
||||
import subprocess
|
||||
import tempfile
|
||||
import zipfile
|
||||
import shutil
|
||||
import sys
|
||||
import os
|
||||
|
||||
from PIL import Image, ImageOps
|
||||
from modules import logger
|
||||
from modules import logger, mscz
|
||||
|
||||
RATIO = 16/9 # 16:9
|
||||
|
||||
|
||||
def get_elements(root, attribute):
|
||||
return [i for i in root if i.tag == attribute]
|
||||
|
||||
def get_element(root, attribute):
|
||||
elems = get_elements(root, attribute)
|
||||
|
||||
if len(elems) > 1:
|
||||
print(f"More than one '{attribute}' found", file=sys.stderr)
|
||||
if len(elems) == 0:
|
||||
raise IndexError(f"No '{attribute}' found !")
|
||||
|
||||
return elems[0]
|
||||
|
||||
def create_pagebreaks(data):
|
||||
"""
|
||||
Replaces all manual linebreaks by pagebreaks in a .mscx file (xml)
|
||||
"""
|
||||
root = ElementTree.fromstring(data)
|
||||
|
||||
score = get_element(root, "Score")
|
||||
parts = get_elements(score, "Part")
|
||||
staffs = get_elements(score, "Staff")
|
||||
for part in parts:
|
||||
staffs += get_elements(part, "Staff")
|
||||
|
||||
changes = 0
|
||||
for staff in staffs:
|
||||
measures = get_elements(staff, "Measure")
|
||||
for measure in measures:
|
||||
layoutbreaks = get_elements(measure, "LayoutBreak")
|
||||
for layoutbreak in layoutbreaks:
|
||||
subtype = get_element(layoutbreak, "subtype")
|
||||
if subtype.text == "line":
|
||||
subtype.text = "page"
|
||||
changes += 1
|
||||
|
||||
|
||||
return ElementTree.tostring(root), changes
|
||||
|
||||
def remove_footer(data):
|
||||
"""
|
||||
Disable page footer in .mss (xml)
|
||||
"""
|
||||
root = ElementTree.fromstring(data)
|
||||
|
||||
style = get_element(root, "Style")
|
||||
show_footer = get_element(style, "showFooter")
|
||||
show_footer.text = 0
|
||||
|
||||
return ElementTree.tostring(root)
|
||||
|
||||
def prepare_mscz(source, dest):
|
||||
shutil.copy(source, dest)
|
||||
with zipfile.ZipFile(source) as inzip, zipfile.ZipFile(dest, "w") as outzip:
|
||||
for inzipinfo in inzip.infolist():
|
||||
with inzip.open(inzipinfo) as infile:
|
||||
if inzipinfo.filename.endswith(".mscx"):
|
||||
new_data, changes = create_pagebreaks(infile.read())
|
||||
outzip.writestr(inzipinfo.filename, new_data)
|
||||
elif inzipinfo.filename.endswith(".mss"):
|
||||
new_data = remove_footer(infile.read())
|
||||
outzip.writestr(inzipinfo.filename, new_data)
|
||||
else:
|
||||
outzip.writestr(inzipinfo.filename, infile.read())
|
||||
|
||||
def generate_images(mscz_file, base_dest):
|
||||
with tempfile.TemporaryDirectory() as tmpdirname:
|
||||
tmp_mscz = os.path.join(tmpdirname, "score.mscz")
|
||||
prepare_mscz(mscz_file, tmp_mscz)
|
||||
mscz.apply(
|
||||
mscz_file,
|
||||
tmp_mscz,
|
||||
[
|
||||
mscz.patches.create_pagebreaks,
|
||||
mscz.patches.remove_footer
|
||||
]
|
||||
)
|
||||
logger.log(".mscz file patched")
|
||||
|
||||
subprocess.call(["mscore", tmp_mscz, "-o", base_dest+".png"])
|
||||
|
@ -1,22 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
IN=$1
|
||||
[[ $IN ]]|| IN="concat.txt"
|
||||
FILES=$(cat $IN | grep file | awk '{print $2}' | uniq)
|
||||
|
||||
echo $FILES
|
||||
|
||||
# Get the larger width and height of all the images
|
||||
WIDTH=$(identify -format "%w\n" $FILES | sort -nr | head -1)
|
||||
HEIGHT=$(identify -format "%h\n" $FILES | sort -nr | head -1)
|
||||
|
||||
echo $WIDTH x $HEIGHT
|
||||
|
||||
# Center all the images and pad them to the larger width and height
|
||||
# Set the border color to the dominant color of the image
|
||||
for f in $FILES; do
|
||||
BORDER_COLOR=$(magick $f -format "%[pixel:p{0,0}]" info:)
|
||||
#BORDER_COLOR="srgb(255,255,255)"
|
||||
echo "Border color: $BORDER_COLOR"
|
||||
magick $f -gravity center -background none -extent ${WIDTH}x${HEIGHT} -bordercolor $BORDER_COLOR -border 0x0 $f
|
||||
done
|
111
src/modules/mscz.py
Normal file
111
src/modules/mscz.py
Normal file
@ -0,0 +1,111 @@
|
||||
from xml.etree import ElementTree
|
||||
import functools
|
||||
import zipfile
|
||||
import shutil
|
||||
|
||||
|
||||
"""
|
||||
Patches
|
||||
"""
|
||||
class Patches:
|
||||
def __init__(self):
|
||||
self._data = {}
|
||||
def __getattr__(self, key):
|
||||
return self._data[key]
|
||||
|
||||
|
||||
patches = Patches()
|
||||
|
||||
def register_patch(file_ext):
|
||||
def inner_wrapper(view):
|
||||
patches._data[view.__name__] = (view, file_ext)
|
||||
|
||||
@functools.wraps(view)
|
||||
def wrapped_view(**kwargs):
|
||||
return view(**kwargs)
|
||||
|
||||
return wrapped_view
|
||||
return inner_wrapper
|
||||
|
||||
|
||||
@register_patch("mscx")
|
||||
def create_pagebreaks(data):
|
||||
"""
|
||||
Replaces all manual linebreaks by pagebreaks in a .mscx file (xml)
|
||||
"""
|
||||
root = ElementTree.fromstring(data)
|
||||
|
||||
score = get_element(root, "Score")
|
||||
parts = get_elements(score, "Part")
|
||||
staffs = get_elements(score, "Staff")
|
||||
for part in parts:
|
||||
staffs += get_elements(part, "Staff")
|
||||
|
||||
for staff in staffs:
|
||||
measures = get_elements(staff, "Measure")
|
||||
for measure in measures:
|
||||
layoutbreaks = get_elements(measure, "LayoutBreak")
|
||||
for layoutbreak in layoutbreaks:
|
||||
subtype = get_element(layoutbreak, "subtype")
|
||||
if subtype.text == "line":
|
||||
subtype.text = "page"
|
||||
|
||||
|
||||
return ElementTree.tostring(root)
|
||||
|
||||
@register_patch("mss")
|
||||
def remove_footer(data):
|
||||
"""
|
||||
Disable page footer in .mss (xml)
|
||||
"""
|
||||
root = ElementTree.fromstring(data)
|
||||
|
||||
style = get_element(root, "Style")
|
||||
show_footer = get_element(style, "showFooter")
|
||||
show_footer.text = 0
|
||||
|
||||
return ElementTree.tostring(root)
|
||||
|
||||
|
||||
"""
|
||||
The "main" apply function
|
||||
"""
|
||||
def get_elements(root, attribute):
|
||||
return [i for i in root if i.tag == attribute]
|
||||
|
||||
def get_element(root, attribute):
|
||||
elems = get_elements(root, attribute)
|
||||
|
||||
if len(elems) > 1:
|
||||
print(f"More than one '{attribute}' found", file=sys.stderr)
|
||||
if len(elems) == 0:
|
||||
raise IndexError(f"No '{attribute}' found !")
|
||||
|
||||
return elems[0]
|
||||
|
||||
def apply(source, dest, patches):
|
||||
"""
|
||||
Apply functions to patch files inside a mscz
|
||||
- source : source file
|
||||
- dest : destination file, must differ
|
||||
- patches : list of (function, file extension)
|
||||
"""
|
||||
patches_by_ext = {}
|
||||
for func, ext in patches:
|
||||
if ext not in patches_by_ext:
|
||||
patches_by_ext[ext] = []
|
||||
|
||||
patches_by_ext[ext].append(func)
|
||||
|
||||
shutil.copy(source, dest)
|
||||
with zipfile.ZipFile(source) as inzip, zipfile.ZipFile(dest, "w") as outzip:
|
||||
for inzipinfo in inzip.infolist():
|
||||
with inzip.open(inzipinfo) as infile:
|
||||
ext = inzipinfo.filename.split(".")[-1]
|
||||
if ext in patches_by_ext:
|
||||
data = infile.read()
|
||||
for func in patches_by_ext[ext]:
|
||||
data = func(data)
|
||||
outzip.writestr(inzipinfo.filename, data)
|
||||
else:
|
||||
outzip.writestr(inzipinfo.filename, infile.read())
|
Loading…
Reference in New Issue
Block a user