Beispiel #1
0
    def __init__(self, structure, sections, progressions, **extra):
        self._structure = []
        self._colorGenerator = RandomColorGenerator()

        super(Structure, self).__init__(structure, sections, progressions, **extra)
Beispiel #2
0
class Structure(BaseStructure):
    """
    Класс для графической презентации структуры песни
    """

    def __init__(self, structure, sections, progressions, **extra):
        self._structure = []
        self._colorGenerator = RandomColorGenerator()

        super(Structure, self).__init__(structure, sections, progressions, **extra)

    def finishStructure(self):
        """
        Окончание обработки структуры

        Генерируем цвета
        """
        self._colorGenerator.generateColors()

    def processSection(self, section, spIter):
        """
        Обработка содержимого секции

        :type section: xml.dom.minidom.Element
        :type spIter: SectionProgressionsIterator
        :rtype: None
        """
        title = section.getAttribute("title")

        progressions = []
        for progression, repeats in imap(itemgetter(0), groupby(imap(lambda x: (x[0], x[2]), spIter))):
            chords = [Chord(x, self._colorGenerator[(progression.title, x.name)]) for x in progression.rawChords]
            progressions.append(Progression(progression.title, repeats, chords))
        repeats = getAttr(section, "repeat", False, validator.repeats, 1)
        self._structure.append(Section(title, repeats, progressions))

    def drawStructure(self, W, H, wEff):
        """
        Генерация изображения со структурой

        :type H: int
        :type W: int
        :type wEff: int
        """

        lines = sum(x.repeats * len(x.progressions) for x in self._structure)
        extraH = settings.STRUCTURE_LINE_SPACE * (lines + len(self._structure) - 1) + settings.STRUCTURE_GROUP_SPACE * (
            len(self._structure) - 1
        )
        lineH = (H - extraH) // (lines + len(self._structure))

        maxBarSize = max(progression.length() for section in self._structure for progression in section.progressions)

        im = Image.new("RGBA", (W, H))
        draw = ImageDraw.Draw(im)
        font = ImageFont.truetype(os.path.join("res", "DejaVuSans.ttf"), int(lineH * 0.9))
        draw.setfont(font)

        yPos = 0

        for section in self._structure:
            title = section.title
            if section.repeats > 1:
                title += " x%d" % section.repeats
            draw.text((4, yPos), title)
            yPos += lineH + settings.STRUCTURE_LINE_SPACE

            for progression in section.progressions:
                xPos = 0
                pos = Length(0, 1)
                for chord in progression.chords:
                    pos += chord.length
                    barX = 2 * pos.count(maxBarSize) * wEff // 3
                    draw.rectangle([(xPos, yPos), (barX, yPos + lineH)], outline="black", fill=str(chord.color))

                    xPos = barX

                xPos = 2 * wEff // 3
                title = [
                    x for x in [progression.title, "x%d" % progression.repeats if progression.repeats > 1 else ""] if x
                ]
                draw.text((xPos + 4, int(round(yPos + lineH * 0.05))), " ".join(title))

                yPos += settings.STRUCTURE_LINE_SPACE + lineH

            yPos += settings.STRUCTURE_GROUP_SPACE

        del draw
        return im