Exemple #1
0
def get_main_plane_coeffs(plane_size, ratio, height):
  card_height = mm_to_px(0.36 * height)
  shrink_x = (plane_size[0] - (plane_size[0] * ratio)) / 2
  return find_coefficients(
    [
      (shrink_x, - card_height * ratio),
      (plane_size[0] - shrink_x, - card_height * ratio),
      (plane_size[0], plane_size[1] * ratio - card_height),
      (0, plane_size[1] * ratio - card_height)
    ],
    [(0, 0), (plane_size[0], 0), (plane_size[0], plane_size[1]), (0, plane_size[1])]
  )
Exemple #2
0
def transform_play_board(board, height):
  scale = 5
  board = resize(board, (int(board.width / scale), int(board.height / scale)))
  height /= 5

  coeffs = get_main_plane_coeffs(board.size, .5, height)
  res = get_play_board()

  board = rotate(board, 80)
  board = transform(board, board.size, Image.PERSPECTIVE, coeffs)

  res.paste(board, mm_to_px(-15, 10), mask=board)
  return res
Exemple #3
0
def dashed_line(draw, xy, fill, width):
    dir = (xy[1][0] - xy[0][0], xy[1][1] - xy[0][1])
    total_dist = sqrt(pow(dir[0], 2) + pow(dir[1], 2))
    step_dist = mm_to_px(1)
    step = (dir[0] * step_dist / total_dist, dir[1] * step_dist / total_dist)
    dist = 0
    pos = xy[0]
    while dist + step_dist < total_dist:
        draw.line((pos, (pos[0] + step[0], pos[1] + step[1])), fill, width)
        pos = (pos[0] + 2 * step[0], pos[1] + 2 * step[1])
        dist += 2 * step_dist

    if dist < total_dist:
        draw.line((pos, xy[1]), fill, width)
Exemple #4
0
    def get_card(self):
        card = super().get_card()
        draw = ImageDraw.Draw(card)

        if self.has_title():
            font = get_font(self.title_size)
            colors = get_source_code_coloring(self.title)
            for color in colors:
                draw.text((mm_to_px(10), self.top),
                          colors[color],
                          font=font,
                          fill=getrgb(color))

            height = draw.textsize("A", font)[1]

            self.top += height * 2.05

        if self.has_title() or not self.should_resize:
            font = get_font(self.text_size)
            colors = get_source_code_coloring(self.text)
            for color in colors:
                draw.text((mm_to_px(10), self.top),
                          colors[color],
                          font=font,
                          fill=getrgb(color),
                          spacing=mm_to_px(.8))
        else:
            sc_size = get_source_code_position_n_size(card, self.text, draw)
            font = get_font(sc_size)
            w, h = draw.textsize(self.text, font, spacing=mm_to_px(0.6))
            colors = get_source_code_coloring(self.text)

            for color in colors:
                draw.text(
                    (mm_to_px(10), (card.size[1] - h) // 2 - mm_to_px(2)),
                    colors[color],
                    font=font,
                    fill=getrgb(color),
                    spacing=mm_to_px(0.8))

        if self.is_upside_down:
            card = card.rotate(180)
        return card
Exemple #5
0
    def get_round_rectangle(size, color, radius):
        if isinstance(color, str): color = getrgb(color)
        if not isinstance(color, tuple): color = tuple(color)

        rectangle = Image.new('RGBA', mm_to_px(size), (*color, 0))
        draw = ImageDraw.Draw(rectangle)
        draw.rectangle(mm_to_px(radius / 2, 0, size[0] - (radius / 2),
                                size[1]),
                       fill=color)
        draw.rectangle(mm_to_px(0, radius / 2, size[0],
                                size[1] - (radius / 2)),
                       fill=color)
        draw.ellipse(mm_to_px(0, 0, radius, radius), fill=color)
        draw.ellipse(mm_to_px(size[0] - radius, 0, size[0], radius),
                     fill=color)
        draw.ellipse(mm_to_px(0, size[1] - radius, radius, size[1]),
                     fill=color)
        draw.ellipse(mm_to_px(size[0] - radius, size[1] - radius, size[0],
                              size[1]),
                     fill=color)

        return rectangle
Exemple #6
0
    def draw_lines(self, draw):
        lines = self.text.get_lines()

        font = get_font(self.font_size)
        spacing = mm_to_px(self.font_size / 15.)

        hyphen_size = draw.textsize("-", font)[0]
        space_size = draw.textsize(" ", font)[0]

        line_height = draw.textsize("A", font)[1] + spacing
        x = y = 0
        disable_x_reset = False

        help_tone_font = get_font(get_max_font_size(draw, "A", space_size, None, self.font_size)[0])
        chords = set()

        if len(lines) > 0 and lines[0].text.startswith("[capo"):
            capo_font = get_font(self.list_font_size)
            width, height = draw.textsize(lines[0].text, capo_font)
            draw.text(
                (
                    self.text_pos[0] + self.max_width - width - mm_to_px(self.delta) // 2,
                    self.text_pos[1] - 1.9 * height
                ),
                lines[0].text,
                font=capo_font, fill=(0, 0, 0))
            lines.pop(0)
            if len(lines) > 0 and lines[0].is_empty():
                lines.pop(0)

        for i, line in enumerate(lines):
            if line.is_empty(): disable_x_reset = False
            if not disable_x_reset: x = 0

            previous_line = None if i - 1 < 0 else lines[i - 1]
            next_line = None if i + 1 == len(lines) else lines[i + 1]
            next_next_line = None if i + 2 >= len(lines) else lines[i + 2]

            if line.is_chord_line() and previous_line is not None and previous_line.is_text_line() and not line.is_tag_line():
                y += spacing / 2

            if line.is_text_line() and previous_line is not None and previous_line.is_chord_line() and not previous_line.is_tag_line():
                continue

            if re.match(r"\[\d+x]", line.text) or (
                    line.is_tag_line() and next_line is not None and next_line.is_chord_line() and not next_line.is_tag_line() and next_next_line is not None and next_next_line.is_chord_line()
            ):
                tag = line.text.split(" ")[0] + " "
                extra = line_height if not next_line.is_text_line() and next_next_line is not None and next_next_line.is_text_line() else 0
                draw.text((self.text_pos[0] + x, self.text_pos[1] + y + extra), tag, font=font, fill=(0, 0, 0))
                line.text = line.text[len(tag):]
                x = draw.textsize(tag, font)[0]
                disable_x_reset = True
                y -= line_height

            if line.is_chord_line() and next_line is not None and next_line.is_text_line() and not line.is_tag_line():
                parts = line.get_parts_with_indexes()
                text_parts = next_line.get_parts_by_indexes([i for i, _ in parts], False)
                chord_parts = line.get_parts_by_indexes([i for i, _ in parts], False)
                if parts[0][0] != 0:
                    chord_parts.insert(0, (0, ""))
                    text_parts.insert(0, (0, next_line.text[:parts[0][0]]))

                extra = -space_size if next_line.text.startswith(" ") else 0
                for i in range(len(chord_parts)):
                    chord = chord_parts[i][1].replace("_", " ").replace("—", "-")
                    while chord.endswith("  "): chord = chord[:-1]
                    text = text_parts[i][1].replace("_", " ").replace("—", "-")
                    while text != text.replace("--", "-"):
                        text = text.replace("--", "-")

                    chord_size = draw.textsize(chord, font)[0]
                    text_size = draw.textsize(text, font)[0]
                    dx = max(chord_size, text_size)
                    if i < len(chord_parts) - 1 and \
                            len(text) > 0 and \
                            text[-1] not in " _," and \
                            len(text_parts[i + 1][1]) > 0 and \
                            text_parts[i + 1][1][0] not in " _,":
                        while text_size + hyphen_size <= dx:
                            text_size += hyphen_size
                            text += "-"

                        if text_parts[i + 1][1][0] == "-":
                            text_parts[i + 1] = (text_parts[i + 1][0], " " + text_parts[i + 1][1][1:])
                            if text_size + hyphen_size <= dx + draw.textsize(" ", font)[0]:
                                text += "-"

                    draw.text((self.text_pos[0] + x + extra, self.text_pos[1] + y), chord, font=font, fill=(0, 0, 0))
                    draw.text((self.text_pos[0] + x + extra, self.text_pos[1] + y + line_height), text, font=font,
                              fill=(0, 0, 0))

                    chord = chord.strip()
                    if len(chord) > 0:
                        if Chord.is_chord(chord):
                            chords.add(str(Chord(chord).tone))
                        # draw.text((self.text_pos[0] + x + extra + chord_size,
                        #            self.text_pos[1] + y),
                        #           str(chord.tone), font=help_tone_font, fill=(0, 0, 0))

                    extra += dx

                y += line_height

            else:
                line.text = line.text.replace("_", " ").replace("—", "-").rstrip()
                draw.text((self.text_pos[0] + x, self.text_pos[1] + y), line.text, font=font, fill=(0, 0, 0))

            y += line_height

        print("chords:", len(chords), chords)
Exemple #7
0
 def get_page(self):
     page = Image.new("RGB", mm_to_px(self.page_size), (255, 255, 255))
     draw = ImageDraw.Draw(page)
     self.draw_lines(draw)
     return page
Exemple #8
0
class RenderedText(object):
    page_size = (210, 297)
    delta = 15
    draw = ImageDraw.Draw(Image.new("RGB", mm_to_px(page_size), (255, 255, 255)))
    title_font_size = get_max_font_size(draw, "A", None, mm_to_px(delta * .7), 100)[0]
    author_font_size = title_font_size * 30 // 40
    text_font_size = title_font_size * 25 // 40
    list_font_size = title_font_size * 20 // 40
    note_font_size = title_font_size * 15 // 40
    max_width = mm_to_px(page_size[0] - 2 * delta)
    max_height = mm_to_px(page_size[1] - 4.5 * delta)
    text_pos = mm_to_px(delta, 3 * delta)

    def __init__(self, text, min_font_size, transposed_by, font_size=text_font_size):
        self.text = SongText(None, text)
        self.transposed_by = transposed_by
        self.font_size, self.problems = get_max_font_size(
            self.draw, self.text.get_text_to_size(), self.max_width, self.max_height, font_size,
            min_font_size=min_font_size)

    def get_page(self):
        page = Image.new("RGB", mm_to_px(self.page_size), (255, 255, 255))
        draw = ImageDraw.Draw(page)
        self.draw_lines(draw)
        return page

    def draw_lines(self, draw):
        lines = self.text.get_lines()

        font = get_font(self.font_size)
        spacing = mm_to_px(self.font_size / 15.)

        hyphen_size = draw.textsize("-", font)[0]
        space_size = draw.textsize(" ", font)[0]

        line_height = draw.textsize("A", font)[1] + spacing
        x = y = 0
        disable_x_reset = False

        help_tone_font = get_font(get_max_font_size(draw, "A", space_size, None, self.font_size)[0])
        chords = set()

        if len(lines) > 0 and lines[0].text.startswith("[capo"):
            capo_font = get_font(self.list_font_size)
            width, height = draw.textsize(lines[0].text, capo_font)
            draw.text(
                (
                    self.text_pos[0] + self.max_width - width - mm_to_px(self.delta) // 2,
                    self.text_pos[1] - 1.9 * height
                ),
                lines[0].text,
                font=capo_font, fill=(0, 0, 0))
            lines.pop(0)
            if len(lines) > 0 and lines[0].is_empty():
                lines.pop(0)

        for i, line in enumerate(lines):
            if line.is_empty(): disable_x_reset = False
            if not disable_x_reset: x = 0

            previous_line = None if i - 1 < 0 else lines[i - 1]
            next_line = None if i + 1 == len(lines) else lines[i + 1]
            next_next_line = None if i + 2 >= len(lines) else lines[i + 2]

            if line.is_chord_line() and previous_line is not None and previous_line.is_text_line() and not line.is_tag_line():
                y += spacing / 2

            if line.is_text_line() and previous_line is not None and previous_line.is_chord_line() and not previous_line.is_tag_line():
                continue

            if re.match(r"\[\d+x]", line.text) or (
                    line.is_tag_line() and next_line is not None and next_line.is_chord_line() and not next_line.is_tag_line() and next_next_line is not None and next_next_line.is_chord_line()
            ):
                tag = line.text.split(" ")[0] + " "
                extra = line_height if not next_line.is_text_line() and next_next_line is not None and next_next_line.is_text_line() else 0
                draw.text((self.text_pos[0] + x, self.text_pos[1] + y + extra), tag, font=font, fill=(0, 0, 0))
                line.text = line.text[len(tag):]
                x = draw.textsize(tag, font)[0]
                disable_x_reset = True
                y -= line_height

            if line.is_chord_line() and next_line is not None and next_line.is_text_line() and not line.is_tag_line():
                parts = line.get_parts_with_indexes()
                text_parts = next_line.get_parts_by_indexes([i for i, _ in parts], False)
                chord_parts = line.get_parts_by_indexes([i for i, _ in parts], False)
                if parts[0][0] != 0:
                    chord_parts.insert(0, (0, ""))
                    text_parts.insert(0, (0, next_line.text[:parts[0][0]]))

                extra = -space_size if next_line.text.startswith(" ") else 0
                for i in range(len(chord_parts)):
                    chord = chord_parts[i][1].replace("_", " ").replace("—", "-")
                    while chord.endswith("  "): chord = chord[:-1]
                    text = text_parts[i][1].replace("_", " ").replace("—", "-")
                    while text != text.replace("--", "-"):
                        text = text.replace("--", "-")

                    chord_size = draw.textsize(chord, font)[0]
                    text_size = draw.textsize(text, font)[0]
                    dx = max(chord_size, text_size)
                    if i < len(chord_parts) - 1 and \
                            len(text) > 0 and \
                            text[-1] not in " _," and \
                            len(text_parts[i + 1][1]) > 0 and \
                            text_parts[i + 1][1][0] not in " _,":
                        while text_size + hyphen_size <= dx:
                            text_size += hyphen_size
                            text += "-"

                        if text_parts[i + 1][1][0] == "-":
                            text_parts[i + 1] = (text_parts[i + 1][0], " " + text_parts[i + 1][1][1:])
                            if text_size + hyphen_size <= dx + draw.textsize(" ", font)[0]:
                                text += "-"

                    draw.text((self.text_pos[0] + x + extra, self.text_pos[1] + y), chord, font=font, fill=(0, 0, 0))
                    draw.text((self.text_pos[0] + x + extra, self.text_pos[1] + y + line_height), text, font=font,
                              fill=(0, 0, 0))

                    chord = chord.strip()
                    if len(chord) > 0:
                        if Chord.is_chord(chord):
                            chords.add(str(Chord(chord).tone))
                        # draw.text((self.text_pos[0] + x + extra + chord_size,
                        #            self.text_pos[1] + y),
                        #           str(chord.tone), font=help_tone_font, fill=(0, 0, 0))

                    extra += dx

                y += line_height

            else:
                line.text = line.text.replace("_", " ").replace("—", "-").rstrip()
                draw.text((self.text_pos[0] + x, self.text_pos[1] + y), line.text, font=font, fill=(0, 0, 0))

            y += line_height

        print("chords:", len(chords), chords)
Exemple #9
0
                               resample=ANTIALIASING))
                f3.write(
                    img.resize(mm_to_px((210 / 2, 297 / 2)),
                               resample=ANTIALIASING))

            # songs = songs[:2]
            # songs = [song for song in songs if song.title.startswith("A")]
            # songs.sort(key=lambda song: len(song.text.text.split("\n")))
            draw = ImageDraw.Draw(Image.new("RGB", (0, 0), (255, 255, 255)))

            num_of_pages = 1
            while True:
                i = (len(songs) + 1) // num_of_pages
                list_font_size = get_max_font_size(
                    draw, "\n".join(["A" for a in range(i // 2)]), None,
                    mm_to_px(RenderedText.page_size[1] -
                             RenderedText.delta * 5),
                    RenderedText.text_font_size)[0]
                if list_font_size >= RenderedText.list_font_size:
                    break
                num_of_pages += 1

            f.counter = num_of_pages * 2 + 1
            f2.counter = num_of_pages * 2 + 1
            f3.counter = num_of_pages * 2 + 1

            single_song_waiting_for_another = None
            worst = []

            written_songs = []
            c = 0
Exemple #10
0
def generate_pdf(name, cards):
    random.seed(10)

    with PdfWriter(name) as writer:
        counter = 0

        space = .05
        base_point = int(mm_to_px(210) / 2 - mm_to_px(Card.base_width) - mm_to_px(space / 2)), \
                     int(mm_to_px(297) / 2 - 2.5 * mm_to_px(Card.base_height) - mm_to_px(space * 2))

        while len(cards) > 0:
            front_canvas = Image.new("RGB", mm_to_px(210, 297),
                                     (255, 255, 255))
            back_canvas = Image.new("RGB", mm_to_px(210, 297), (255, 255, 255))
            for i in range(len(cards[:10])):
                card = cards.pop(0)
                counter += 1
                print("{} Generating {}. card".format(datetime.now(), counter))
                sys.stdout.flush()

                card = card.get_card()
                offset_x = mm_to_px(Card.base_width +
                                    space) if i % 2 == 1 else 0
                offset_y = mm_to_px(Card.base_height + space) * (i // 2)

                if card[0].size[0] > 0:
                    front_canvas.paste(
                        card[0],
                        (base_point[0] + offset_x, base_point[1] + offset_y),
                        mask=card[0])
                offset_x = mm_to_px(Card.base_width +
                                    space) if i % 2 == 0 else 0
                background = Card.get_round_rectangle(
                    ((card[1].size[0] // mm_to_px(Card.base_width)) *
                     Card.base_width + 4,
                     (card[1].size[1] // mm_to_px(Card.base_height)) *
                     Card.base_height + 4), "true_black", 0)

                if card[1].size[0] > 0:
                    back_canvas.paste(background,
                                      (base_point[0] + offset_x - mm_to_px(2),
                                       base_point[1] + offset_y - mm_to_px(2)),
                                      mask=background)
                    back_canvas.paste(
                        card[1],
                        (base_point[0] + offset_x, base_point[1] + offset_y),
                        mask=card[1])

            if not all([p == (255, 255, 255) for p in front_canvas.getdata()]):
                writer.write(front_canvas)
            if not all([p == (255, 255, 255) for p in back_canvas.getdata()]):
                writer.write(back_canvas)
Exemple #11
0
def generate_box(name):
    with PdfWriter(name) as f:
        extra_space_around_cards = 1
        extra_space_because_of_how_box_is_folded = 2
        for diff in [0, 1]:
            w = mm_to_px(Card.base_width + diff + extra_space_around_cards)
            l = mm_to_px((Card.base_height + diff) * 2 +
                         extra_space_around_cards +
                         extra_space_because_of_how_box_is_folded)
            h = mm_to_px(22)
            mx = max(w // 2, h * 2)
            mn = min(w // 2, h * 2)
            margin = mm_to_px(30)

            for i in range(2):
                cropping = mm_to_px(2) if i == 0 else 0

                page = Image.new("RGB", mm_to_px(210, 297), (255, 255, 255))
                draw = ImageDraw.Draw(page)
                color = getrgb("black") if diff == 0 else getrgb("true_black")
                draw.rectangle(
                    ((margin - cropping, margin + mx - w // 2 - cropping),
                     (margin + h + w + h + cropping,
                      margin + mx + l + w // 2 + cropping)), color)
                draw.rectangle(
                    ((margin + h - cropping, margin + mx - h * 2 - cropping),
                     (margin + h + w + cropping,
                      margin + mx + l + h * 2 + cropping)), color)

                if i == 0 and diff == 1:
                    card = BackCard(px_to_mm(w), px_to_mm(l), True,
                                    "orange").get_card()
                    page.paste(card, (margin + h, margin + mx), mask=card)

                if i == 1:
                    line_color = getrgb("white")
                    line_width = mm_to_px(.05)
                    draw.line((
                        (margin + h, margin + mx + l + mn),
                        (margin + h, margin + mx + l),
                    ), line_color, line_width)
                    draw.line((
                        (margin + h + w, margin + mx + l),
                        (margin + h + w, margin + mx + l + mn),
                    ), line_color, line_width)
                    draw.line((
                        (margin + h + w, margin + mx - mn),
                        (margin + h + w, margin + mx),
                    ), line_color, line_width)
                    draw.line((
                        (margin + h, margin + mx - mn),
                        (margin + h, margin + mx),
                    ), line_color, line_width)

                    dashed_line(draw, ((margin + h, margin + mx - h),
                                       (margin + h + w, margin + mx - h)),
                                line_color, line_width)

                    dashed_line(draw, ((margin, margin + mx),
                                       (margin + h, margin + mx)), line_color,
                                line_width)
                    dashed_line(draw, ((margin + h, margin + mx),
                                       (margin + h + w, margin + mx)),
                                line_color, line_width)
                    dashed_line(draw, ((margin + h + w, margin + mx),
                                       (margin + h + w + h, margin + mx)),
                                line_color, line_width)

                    dashed_line(draw, ((margin, margin + mx + l),
                                       (margin + h, margin + mx + l)),
                                line_color, line_width)
                    dashed_line(draw, ((margin + h, margin + mx + l),
                                       (margin + h + w, margin + mx + l)),
                                line_color, line_width)
                    dashed_line(draw, ((margin + h + w, margin + mx + l),
                                       (margin + h + w + h, margin + mx + l)),
                                line_color, line_width)

                    dashed_line(draw, ((margin + h, margin + mx + l + h),
                                       (margin + h + w, margin + mx + l + h)),
                                line_color, line_width)

                    dashed_line(draw, ((margin + h, margin + mx),
                                       (margin + h, margin + mx + l)),
                                line_color, line_width)
                    dashed_line(draw, ((margin + h + w, margin + mx),
                                       (margin + h + w, margin + mx + l)),
                                line_color, line_width)

                if i == 1:
                    page = page.transpose(FLIP_LEFT_RIGHT)
                f.write(page)
Exemple #12
0
 def get_blank(self):
     return Image.new("RGBA", mm_to_px(self.size()), (0, 0, 0, 0))
Exemple #13
0
class TextHelpCard(HelpCard):
    delta = mm_to_px(10)
    title_size = 14
    text_size = 11

    def __init__(self, color, title, text):
        self.should_resize = False
        self.title = title
        self.text = text
        self.title = self.title.strip()
        self.top = self.delta
        super().__init__(color)

        self.check_sizes()
        self.is_upside_down = False

    def has_title(self):
        return len(self.title) > 0

    def get_card(self):
        card = super().get_card()
        draw = ImageDraw.Draw(card)

        if self.has_title():
            font = get_font(self.title_size)
            colors = get_source_code_coloring(self.title)
            for color in colors:
                draw.text((mm_to_px(10), self.top),
                          colors[color],
                          font=font,
                          fill=getrgb(color))

            height = draw.textsize("A", font)[1]

            self.top += height * 2.05

        if self.has_title() or not self.should_resize:
            font = get_font(self.text_size)
            colors = get_source_code_coloring(self.text)
            for color in colors:
                draw.text((mm_to_px(10), self.top),
                          colors[color],
                          font=font,
                          fill=getrgb(color),
                          spacing=mm_to_px(.8))
        else:
            sc_size = get_source_code_position_n_size(card, self.text, draw)
            font = get_font(sc_size)
            w, h = draw.textsize(self.text, font, spacing=mm_to_px(0.6))
            colors = get_source_code_coloring(self.text)

            for color in colors:
                draw.text(
                    (mm_to_px(10), (card.size[1] - h) // 2 - mm_to_px(2)),
                    colors[color],
                    font=font,
                    fill=getrgb(color),
                    spacing=mm_to_px(0.8))

        if self.is_upside_down:
            card = card.rotate(180)
        return card

    def check_sizes(self):
        if len(self.title) > 31:
            logging.warning(f"Title {self.title} is too long! (31 chars max)")

        lines = self.text.split("\n")
        lines.sort(reverse=True, key=lambda line: len(line))
        line = lines[0]
        if len(line) > 42:
            logging.warning(f"Line {line} is too long! (42 chars max)")

        if len(lines) > (27 if self.has_title() else 29):
            logging.warning(
                f"There is too many lines ({len(lines)}), max. lines count is 27 (29), in {self}"
            )

    def __repr__(self):
        if self.has_title():
            return self.title

        return self.text.split("\n")[0]
Exemple #14
0
def get_first_image():
  background = ImageColor.getrgb(color_codes["lighter_black"])

  fn = Image.new("RGBA", mm_to_px(200, 150), (*background, 0))
  fn_back = rotate(PlayingCardBack("yellow").get_card(), 90)
  fn.paste(fn_back, mm_to_px(00, 45), fn_back)

  value = Image.new("RGBA", mm_to_px(200, 150), (*background, 0))
  value_back = rotate(PlayingCardBack("blue").get_card(), 90)
  value.paste(value_back, mm_to_px(70, 45), value_back)

  corner_size = 20
  cropped_fn = Image.new("RGBA", mm_to_px(200, 150), (*background, 0))
  cropped_fn_back = rotate(PlayingCardBack("yellow").get_card(), 90)
  for w in range(cropped_fn_back.width):
    for h in range(cropped_fn_back.height):
      if w - h > mm_to_px(Card.base_height - corner_size):
        cropped_fn_back.putpixel((w, h), (0, 0, 0, 0))

  cropped_fn.paste(cropped_fn_back, mm_to_px(00, 45), cropped_fn_back)

  cropped_fn_corner = Image.new("RGBA", mm_to_px(200, 150), (*background, 0))
  cropped_fn_corner_back = rotate(ValueCard("green", values["green"][0]).get_card(), 90)
  for w in range(cropped_fn_corner_back.width):
    for h in range(cropped_fn_corner_back.height):
      if w - h <= mm_to_px(Card.base_height - corner_size - 0.1):
        cropped_fn_corner_back.putpixel((w, h), (0, 0, 0, 0))
        continue
      if w - h <= mm_to_px(Card.base_height - corner_size):
        pix = list(cropped_fn_corner_back.getpixel((w, h)))
        for i in range(len(pix)):
          pix[i] //= 2
        pix[-1] = 255
        cropped_fn_corner_back.putpixel((w, h), tuple(pix))

  cropped_fn_corner_back = rotate(cropped_fn_corner_back, 180,
                                  expand=False, center=mm_to_px(Card.base_height - corner_size // 2, corner_size // 2))
  cropped_fn_corner.paste(cropped_fn_corner_back, mm_to_px(00, 45), cropped_fn_corner_back)

  plane = Image.new("RGB", mm_to_px(200, 150), (*background,))
  blank = Image.new("RGBA", mm_to_px(200, 150), (*background, 255))
  for height in range(16):
    ratio = .8
    coeffs = get_main_plane_coeffs(plane.size, ratio, height - 0.5)
    transformed = transform(value, plane.size, Image.PERSPECTIVE, coeffs)
    plane.paste(blank, mask=transformed)

    if height < 13:
      transformed = transform(fn, plane.size, Image.PERSPECTIVE, coeffs)
      plane.paste(blank, mask=transformed)
    if height == 13:
      transformed = transform(cropped_fn, plane.size, Image.PERSPECTIVE, coeffs)
      plane.paste(blank, mask=transformed)
    if height == 14:
      transformed = transform(cropped_fn_corner, plane.size, Image.PERSPECTIVE, coeffs)
      plane.paste(blank, mask=transformed)

    coeffs = get_main_plane_coeffs(plane.size, ratio, height)
    transformed = transform(value, plane.size, Image.PERSPECTIVE, coeffs)
    plane.paste(transformed, mask=transformed)
    if height <= 14:
      if height < 13:
        transformed = transform(fn, plane.size, Image.PERSPECTIVE, coeffs)
      if height == 13:
        transformed = transform(cropped_fn, plane.size, Image.PERSPECTIVE, coeffs)
      if height == 14:
        transformed = transform(cropped_fn_corner, plane.size, Image.PERSPECTIVE, coeffs)
      plane.paste(transformed, mask=transformed)

  plane = resize(plane, (plane.width // 2, plane.height // 2))

  return plane
Exemple #15
0
def get_play(
    fns_count, values_count,
    input_value_index, output_value_index,
    used_fn_indexes,
    front_hand_count, right_hand_count,
    front_played_count=0, right_played_count=0,
    add_thumb=False
):
  background = ImageColor.getrgb(color_codes["lighter_black"])
  base = Image.new("RGB", mm_to_px(87 - PictureHelpCard.DX, 87 - PictureHelpCard.DX), (*background,))

  x1 = 30
  x2 = 230
  y1 = 30
  y2 = 100

  table = get_play_board()
  table.putalpha(100)
  table = transform_play_board(table, 0)
  base.paste(table, mask=table)

  blank = get_play_board()

  fn = get_play_board()
  fn_card = PlayingCardBack("yellow").get_card()
  fn.paste(fn_card, mm_to_px(x2, y1), fn_card)

  for i in range(fns_count):
    transformed = transform_play_board(fn, i - 0.5)
    base.paste(blank, mask=transformed)
    transformed = transform_play_board(fn, i)
    base.paste(transformed, mask=transformed)

  value = get_play_board()
  value_card = PlayingCardBack("blue").get_card()
  value.paste(value_card, mm_to_px(x1, y1), value_card)

  for i in range(values_count):
    transformed = transform_play_board(value, i - 0.5)
    base.paste(blank, mask=transformed)
    transformed = transform_play_board(value, i)
    base.paste(transformed, mask=transformed)

  used_value = get_play_board()
  used_value_card = ValueCard("green", values["green"][0]).get_card()
  used_value.paste(used_value_card, mm_to_px(x1, y2), used_value_card)

  for i in range(14 - values_count - 1):
    transformed = transform_play_board(used_value, i - 0.5)
    base.paste(blank, mask=transformed)
    transformed = transform_play_board(used_value, i)
    base.paste(transformed, mask=transformed)

  if input_value_index is not None:
    input_value = get_play_board()
    input_value_card = ValueCard("green", values["green"][input_value_index]).get_card()
    input_value.paste(input_value_card, mm_to_px(x1, y2), input_value_card)

    i = 14 - values_count - 1
    transformed = transform_play_board(input_value, i - 0.5)
    base.paste(blank, mask=transformed)
    transformed = transform_play_board(input_value, i)
    base.paste(transformed, mask=transformed)

  if output_value_index is not None:
    output_value = get_play_board()
    output_value_card = ValueCard("green", values["green"][output_value_index]).get_card()
    output_value.paste(output_value_card, mm_to_px(x2, y2), output_value_card)

    i = 0
    transformed = transform_play_board(output_value, i - 0.5)
    base.paste(blank, mask=transformed)
    transformed = transform_play_board(output_value, i)
    base.paste(transformed, mask=transformed)

  for i in range(right_hand_count):
    right_hand = Image.new("RGBA", mm_to_px(200, 200), (0, 0, 0, 0))
    right_hand_tmp = Image.new("RGBA", mm_to_px(200, 200), (0, 0, 0, 0))
    right_hand_card = PlayingCardBack("yellow").get_card()
    right_hand_tmp.paste(right_hand_card, mm_to_px(50, 50), right_hand_card)
    # right_hand_tmp = resize(right_hand_tmp, (2 * right_hand_tmp.size[0], 2 * right_hand_tmp.size[1]))
    right_hand_tmp = rotate(right_hand_tmp, 13 + (-i - 1) * 8,
                            expand=False, center=mm_to_px((Card.base_width + 50, 50)))
    right_hand.paste(right_hand_tmp, mm_to_px(0, 80), right_hand_tmp)
    right_hand = rotate(right_hand, 180)

    coeffs = find_coefficients(
      [
        (mm_to_px(140), mm_to_px(20)),
        (right_hand.size[0] - mm_to_px(20), mm_to_px(40)),
        (right_hand.size[0] - mm_to_px(20), right_hand.size[1] - mm_to_px(130)),
        (mm_to_px(160), right_hand.size[1] - mm_to_px(140))
      ],
      [(0, 0), (right_hand.size[0], 0), (right_hand.size[0], right_hand.size[1]), (0, right_hand.size[1])]
    )
    right_hand = transform(right_hand, right_hand.size, Image.PERSPECTIVE, coeffs)
    scale = 1.5
    right_hand = resize(right_hand, (int(right_hand.width / scale), int(right_hand.height / scale)))
    base.paste(right_hand, mm_to_px(-110 / scale + 23, -30 / scale + 2), mask=right_hand)

  if add_thumb:
    thumb = Image.new("RGBA", mm_to_px(200, 200), (0, 0, 0, 0))
    thumb_tmp = Image.new("RGBA", mm_to_px(200, 200), (0, 0, 0, 0))
    thumb_card = Image.open("help/arrows/thumb.png").convert("RGBA")
    scale = 3. * 80 / ANTIALIASING / RESOLUTION_DPI
    thumb_card = resize(thumb_card, (int(thumb_card.width / scale), int(thumb_card.height / scale)))
    thumb_card = rotate(thumb_card, 180)
    color = getrgb("grey")
    for x in range(thumb_card.width):
      for y in range(thumb_card.height):
        thumb_card.putpixel((x, y), (*color, thumb_card.getpixel((x, y))[3]))
    thumb_tmp.paste(thumb_card, mm_to_px(70, 50), thumb_card)
    thumb_tmp = rotate(thumb_tmp, 13, expand=False, center=mm_to_px((Card.base_width + 50, 50)))
    thumb.paste(thumb_tmp, mm_to_px(0, 80), thumb_tmp)
    thumb = rotate(thumb, 180)

    coeffs = find_coefficients(
      [
        (mm_to_px(140), mm_to_px(20)),
        (thumb.size[0] - mm_to_px(20), mm_to_px(40)),
        (thumb.size[0] - mm_to_px(20), thumb.size[1] - mm_to_px(130)),
        (mm_to_px(160), thumb.size[1] - mm_to_px(140))
      ],
      [(0, 0), (thumb.size[0], 0), (thumb.size[0], thumb.size[1]), (0, thumb.size[1])]
    )
    thumb = transform(thumb, thumb.size, Image.PERSPECTIVE, coeffs)
    scale = 1.5
    thumb = resize(thumb, (int(thumb.width / scale), int(thumb.height / scale)))
    base.paste(thumb, mm_to_px(-110 / scale + 23, -30 / scale + 2), mask=thumb)

  for i in range(len(used_fn_indexes)):
    used_fn = get_play_board()
    used_fn_card = FunctionCard("green", get_rules()["green"][used_fn_indexes[i]]).get_card()
    used_fn_card = rotate(used_fn_card, randint(0, 360))

    used_fn.paste(used_fn_card, mm_to_px(x1 / 2 + x2 / 2 - 5, y2 + 30), used_fn_card)

    transformed = transform_play_board(used_fn, i - 0.5)
    base.paste(blank, mask=transformed)
    transformed = transform_play_board(used_fn, i)
    base.paste(transformed, mask=transformed)

  for i in range(front_played_count):
    i += 1
    front_player_fn = get_play_board()
    front_player_fn_card = PlayingCardBack("yellow").get_card()
    front_player_fn_card = rotate(front_player_fn_card, 97 + 10 * -i)
    front_player_fn.paste(front_player_fn_card,
                          mm_to_px(x1 - 10 + 2 * i + randint(-3, 3), 200 + 20 * i + randint(-3, 3)),
                          front_player_fn_card)

    transformed = transform_play_board(front_player_fn, i - 0.5)
    base.paste(blank, mask=transformed)
    transformed = transform_play_board(front_player_fn, i)
    base.paste(transformed, mask=transformed)

  for i in range(right_played_count):
    i += 1
    right_player_fn = get_play_board()
    right_player_fn_card = PlayingCardBack("yellow").get_card()
    right_player_fn_card = rotate(right_player_fn_card, 51 + 8 * -i)
    right_player_fn.paste(right_player_fn_card,
                          mm_to_px(x2 + 20 + 8 * i + randint(-3, 3), 300 - 20 * i + randint(-3, 3)),
                          right_player_fn_card)

    transformed = transform_play_board(right_player_fn, i - 0.5)
    base.paste(blank, mask=transformed)
    transformed = transform_play_board(right_player_fn, i)
    base.paste(transformed, mask=transformed)

  for i in range(front_hand_count):
    front_hand = Image.new("RGBA", mm_to_px(200, 200), (0, 0, 0, 0))
    front_hand_tmp = Image.new("RGBA", mm_to_px(200, 200), (0, 0, 0, 0))
    front_hand_card = ValueCard("green", values["green"][0]).get_card()
    front_hand_tmp.paste(front_hand_card, mm_to_px(50, 50), front_hand_card)
    # front_hand_tmp = resize(front_hand_tmp, (2 * front_hand_tmp.size[0], 2 * front_hand_tmp.size[1]))
    front_hand_tmp = rotate(front_hand_tmp, -2 + (-i - 1) * 5, expand=False,
                            center=mm_to_px((Card.base_width + 50, Card.base_height + 50)))
    front_hand.paste(front_hand_tmp, mm_to_px(0, 0), front_hand_tmp)

    coeffs = get_main_plane_coeffs(front_hand.size, .9, i)
    front_hand = transform(front_hand, front_hand.size, Image.PERSPECTIVE, coeffs)
    scale = 2
    front_hand = resize(front_hand, (int(front_hand.width / scale), int(front_hand.height / scale)))
    base.paste(front_hand, mm_to_px(-12, 46), mask=front_hand)

  return base
Exemple #16
0
def get_play_board():
  return Image.new("RGBA", mm_to_px(400, 400), (0, 0, 0, 0))