File size: 2,740 Bytes
86eaed9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
import os
import fitz
import subprocess
from PIL import Image
from music21 import converter, interval, clef, stream
from utils import MSCORE


def abc2xml(abc_content, output_xml_path):
    score = converter.parse(abc_content, format="abc")
    score.write("musicxml", fp=output_xml_path, encoding="utf-8")
    return output_xml_path


def xml2(xml_path: str, target_fmt: str):
    src_fmt = os.path.basename(xml_path).split(".")[-1]
    if not "." in target_fmt:
        target_fmt = "." + target_fmt

    target_file = xml_path.replace(f".{src_fmt}", target_fmt)
    print(subprocess.run([MSCORE, "-o", target_file, xml_path]))
    return target_file


def pdf2img(pdf_path: str):
    output_path = pdf_path.replace(".pdf", ".jpg")
    doc = fitz.open(pdf_path)
    # 创建一个图像列表
    images = []
    for page_number in range(doc.page_count):
        page = doc[page_number]
        # 将页面渲染为图像
        image = page.get_pixmap()
        # 将图像添加到列表
        images.append(
            Image.frombytes("RGB", [image.width, image.height], image.samples)
        )
    # 竖向合并图像
    merged_image = Image.new(
        "RGB", (images[0].width, sum(image.height for image in images))
    )
    y_offset = 0
    for image in images:
        merged_image.paste(image, (0, y_offset))
        y_offset += image.height
    # 保存合并后的图像为JPG
    merged_image.save(output_path, "JPEG")
    # 关闭PDF文档
    doc.close()
    return output_path


def xml2img(xml_file: str):
    ext = os.path.basename(xml_file).split(".")[-1]
    pdf_score = xml_file.replace(f".{ext}", ".pdf")
    command = [MSCORE, "-o", pdf_score, xml_file]
    result = subprocess.run(command)
    print(result)
    return pdf_score, pdf2img(pdf_score)


# xml to abc
def xml2abc(input_xml_file: str):
    result = subprocess.run(
        ["python", "-Xfrozen_modules=off", "./xml2abc.py", input_xml_file],
        stdout=subprocess.PIPE,
        text=True,
    )

    if result.returncode == 0:
        return str(result.stdout).strip()

    return ""


def transpose_octaves_abc(abc_notation: str, out_xml_file: str, offset=-12):
    score = converter.parse(abc_notation)
    if offset < 0:
        for part in score.parts:
            for measure in part.getElementsByClass(stream.Measure):
                # 检查当前小节的谱号
                if measure.clef:
                    measure.clef = clef.BassClef()

    octaves_interval = interval.Interval(offset)
    # 遍历每个音符,将其上下移八度
    for note in score.recurse().notes:
        note.transpose(octaves_interval, inPlace=True)

    score.write("musicxml", fp=out_xml_file)
    return xml2abc(out_xml_file), out_xml_file