示例#1
0
def generate_panel(
    panel: dict,
    colors: dict,
    session: Optional[requests.Session] = requests.Session()
) -> Image.Image:
    image = Image.new('RGB', get_size(panel))
    canvas = ImageDraw.Draw(image)
    image2 = Image.new('RGBA', (image.width * 2, image.height * 2))
    canvas2 = ImageDraw.Draw(image2)
    size = get_size(panel)
    background = ImageUtil.ratio_resize(
        ImageUtil.get_image(panel['displayAssets'][0]['background'],
                            session).convert('RGBA'), *size)
    image.paste(background, ImageUtil.center_x(background.width, image.width,
                                               0), background)
    display_asset = ImageUtil.ratio_resize(
        ImageUtil.get_image(panel['displayAssets'][0]['url'],
                            session).convert('RGBA'), *size)
    image.paste(display_asset,
                ImageUtil.center_x(display_asset.width, image.width, 0),
                display_asset)

    canvas.polygon(
        ((0, size[1] - PRICE_HEIGHT), (size[0], size[1] - PRICE_HEIGHT),
         (size[0], size[1]), (0, size[1])),
        fill=(14, 14, 14))
    vbucks = ImageUtil.ratio_resize(
        ImageUtil.open('vbucks.png').point(lambda x: x * 0.8).convert(
            'RGBA').rotate(-15), 40, 40)
    pos = size[0] - vbucks.width - 5
    image.paste(vbucks, (pos, size[1] - vbucks.height + 10), vbucks)
    text = f"{panel['price']['finalPrice']:,}"
    fonts = name_fonts.fonts_size(15, 15, 15)
    x, y = fonts.text_size(text)
    pos = pos - x - 3
    fonts.write_text(canvas,
                     text, (pos, size[1] - y - 4),
                     fill=(160, 175, 185))

    if panel['price']['finalPrice'] != panel['price']['regularPrice']:
        text = f"{panel['price']['regularPrice']:,}"
        fonts = name_fonts.fonts_size(15, 15, 15)
        x, y = fonts.text_size(text)
        pos = pos - x - 6
        fonts.write_text(canvas,
                         text, (pos, size[1] - y - 4),
                         fill=(100, 100, 100))
        canvas2.line((((pos - 2) * 2, (size[1] - y - 4 + 10) * 2),
                      ((pos + x + 3) * 2, (size[1] - y - 4 + 6) * 2)),
                     fill=(100, 110, 110),
                     width=3 * 2)

    canvas2.polygon(
        ((0, (size[1] - PRICE_HEIGHT - NAME_HEIGHT - RARITY_HEIGHT) * 2),
         (size[0] * 2,
          (size[1] - PRICE_HEIGHT - NAME_HEIGHT - RARITY_HEIGHT - SLOPE) * 2),
         (size[0] * 2, (size[1] - PRICE_HEIGHT - NAME_HEIGHT - SLOPE) * 2),
         (0, (size[1] - PRICE_HEIGHT - NAME_HEIGHT) * 2)),
        fill=colors[panel['series']['id']
                    if panel['series'] is not None else panel['rarity']['id']])
    canvas2.polygon(
        ((0, (size[1] - PRICE_HEIGHT - NAME_HEIGHT) * 2),
         (size[0] * 2, (size[1] - PRICE_HEIGHT - NAME_HEIGHT - SLOPE) * 2),
         (size[0] * 2,
          (size[1] - PRICE_HEIGHT) * 2), (0, (size[1] - PRICE_HEIGHT) * 2)),
        fill=(30, 30, 30))
    image2.thumbnail(image.size, Image.LANCZOS)
    image.paste(image2, (0, 0), image2)

    fonts = name_fonts.fonts_size(20, 20, 20)
    x, y = fonts.text_size(panel['displayName'])
    fonts.write_text(canvas,
                     panel['displayName'],
                     ImageUtil.center_x(x, image.width,
                                        size[1] - PRICE_HEIGHT - y - 10),
                     fill=(255, 255, 255))

    icons = [
        ImageUtil.ratio_resize(
            ImageUtil.open(filename).convert('RGBA'), 30, 30)
        for filename in set(
            itertools.chain(*[
                get_user_facing_flag_images(item) for item in panel['granted']
            ]))
    ]
    x = size[0] - 10
    for icon in icons:
        x -= icon.width
        image.paste(icon, (x, size[1] - PRICE_HEIGHT - NAME_HEIGHT -
                           RARITY_HEIGHT - 15 - icon.height), icon)
        x -= 10

    return image
示例#2
0
def generate_section(
    section: dict,
    colors: dict,
    now: datetime.datetime,
    session: Optional[requests.Session] = requests.Session()
) -> Image.Image:
    if len(section['panels']
           ) == 1 and section['panels'][0]['tileSize'] == 'Small':
        image = Image.new('RGBA', (MARGIN_LEFT + get_section_width(section) +
                                   MARGIN_RIGHT, Y_MARGIN + SMALL_SIZE[1]))
    else:
        image = Image.new('RGBA', (MARGIN_LEFT + get_section_width(section) +
                                   MARGIN_RIGHT, Y_MARGIN + NORMAL_SIZE[1]))
    canvas = ImageDraw.Draw(image)

    x = MARGIN_LEFT
    size = 50
    if section['name']:
        fonts = name_fonts.fonts_size(size, size, size)
        x = 50
        final_x, _ = fonts.write_text(canvas, section['name'].upper(),
                                      (x, Y_MARGIN // 2 - 25))
        x += final_x
    if section['until'] is not None:
        timer = ImageUtil.ratio_resize(
            ImageUtil.open('shop_timer.png').convert('RGBA'), size, size)
        x += 12
        image.paste(timer, (x, Y_MARGIN // 2 - 15 - 4), timer)

        end = section['until'] - now
        m, s = divmod(end.seconds, 60)
        h, m = divmod(m, 60)
        timer_text = ("{}:{:0>2}:{:0>2}".format(h, m, s)
                      if end > datetime.timedelta(hours=1) else
                      "{}:{:0>2}".format(m, s))
        x += timer.width + 6
        fonts = name_fonts.fonts_size(size // 2, size // 2, size // 2)
        _, y = fonts.text_size(timer_text)
        fonts.write_text(canvas,
                         timer_text, (x, Y_MARGIN // 2 - 15 + y // 2),
                         fill=(115, 200, 235))

    with ThreadPoolExecutor() as executor:
        futures = [
            executor.submit(generate_panel, panel, colors, session)
            for panel in section['panels']
        ]

    x = MARGIN_LEFT
    small_count = 0
    for num, future in enumerate(futures):
        try:
            panel_image = future.result()
        except Exception:
            print('Failed to generate panel', file=sys.stderr)
            traceback.print_exc()
        else:
            panel = section['panels'][num]
            size = get_size(panel)
            if panel['tileSize'] == 'Small':
                small_count += 1
                if small_count % 2 == 1:
                    pos = (x, Y_MARGIN)
                    x += size[0] + X_MARGIN
                else:
                    pos = (x - size[0] - X_MARGIN,
                           Y_MARGIN + (NORMAL_SIZE[1] - size[1] * 2) + size[1])
            else:
                pos = (x, Y_MARGIN)
                x += size[0] + X_MARGIN
            image.paste(panel_image, pos)
            if panel['banner'] is not None:
                font_size, minus = name_fonts.fit_fonts_size(
                    image.width - 25, 16, panel['banner']['name'])
                fonts = name_fonts.fonts_size(font_size, font_size, font_size)
                text_width = fonts.text_size(panel['banner']['name'])[0]
                banner_height = 32
                color = 'red' if panel['banner'][
                    'intensity'] == 'Low' else 'yellow'
                banner_rear = ImageUtil.ratio_resize(
                    ImageUtil.open(f'{color}_banner_rear.png').convert('RGBA'),
                    0,
                    banner_height,
                    resample=Image.BICUBIC)
                banner_middle = ImageUtil.open(
                    f'{color}_banner_middle.png').convert('RGBA').resize(
                        (text_width, banner_height))
                banner_front = ImageUtil.ratio_resize(ImageUtil.open(
                    f'{color}_banner_front.png').convert('RGBA'),
                                                      0,
                                                      banner_height,
                                                      resample=Image.BICUBIC)
                image.paste(banner_rear, (pos[0] - 15, pos[1] - 15),
                            banner_rear)
                image.paste(banner_middle,
                            (pos[0] - 15 + banner_rear.width, pos[1] - 15),
                            banner_middle)
                image.paste(banner_front, (pos[0] - 15 + banner_rear.width +
                                           banner_middle.width, pos[1] - 15),
                            banner_front)
                fonts.write_text(
                    canvas,
                    panel['banner']['name'],
                    (pos[0] - 15 + banner_rear.width, pos[1] - 15 + 5),
                    fill=(255, 255,
                          255) if panel['banner']['intensity'] == 'Low' else
                    (0, 0, 0))

    return image