def __init__(self, structure, sections, progressions, **extra): self._structure = [] self._colorGenerator = RandomColorGenerator() super(Structure, self).__init__(structure, sections, progressions, **extra)
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