Some prelim work on builder api.
[librarian.git] / src / librarian / covers / widgets / image.py
1 # This file is part of Librarian, licensed under GNU Affero GPLv3 or later.
2 # Copyright © Fundacja Wolne Lektury. See NOTICE for more information.
3 #
4 import PIL.Image
5 import PIL.ImageDraw
6 from librarian import get_resource
7 from .base import Widget
8
9
10 class ImageWidget(Widget):
11     def build(self, w, h):
12         img = PIL.Image.open(self.image_path)
13         img = img.resize((round(img.size[0] / img.size[1] * h), h))
14         return img
15     
16     
17 class WLLogo(ImageWidget):
18     @property
19     def image_path(self):
20         if self.cover.color_scheme['text'] == '#fff':
21             return get_resource('res/cover/logo_WL_invert.png')
22         else:
23             return get_resource('res/cover/logo_WL.png')
24
25
26 class Label(ImageWidget):
27     @property
28     def image_path(self):
29         if self.cover.is_very_bright:
30             return get_resource('res/cover/label_WLpolecaja.szary.png')
31         else:
32             return get_resource('res/cover/label_WLpolecaja.png')
33
34
35 class LogoSticker(ImageWidget):
36     def __init__(self, cover, image_path):
37         self.image_path = image_path
38
39     def apply(self, img, x, y, w, h, padding_x, padding_y, radius):
40         my_img = self.build(w, h, padding_x, padding_y, radius) 
41         if my_img is not None:
42             img.paste(
43                 my_img,
44                 (round(x), round(y - my_img.size[1])),
45                 my_img if self.transparency else None
46             )
47        
48
49     def build(self, w, h, padding_x, padding_y, radius):
50         img = PIL.Image.open(self.image_path)
51         uw, uh = w - 2 * padding_x, h - 2 * padding_y
52         if img.size[1] / img.size[0] > uh / uw:
53             img = img.resize((round(img.size[0] / img.size[1] * uh), uh))
54         else:
55             img = img.resize((uw, round(img.size[1] / img.size[0] * uw)))
56         sz = w, img.size[1] + 2 * padding_y
57         sticker = PIL.Image.new('RGBA', sz)
58         draw = PIL.ImageDraw.Draw(sticker)
59         draw.rectangle((0, radius, sz[0], sz[1] - radius), (0, 0, 0))
60         draw.rectangle((radius, 0, sz[0] - radius, sz[1]), (0, 0, 0))
61         draw.ellipse((0, 0, 2 * radius, 2 * radius), (0, 0, 0))
62         draw.ellipse((0, sz[1] - 2 * radius, 2 * radius, sz[1]), (0, 0, 0))
63         draw.ellipse((sz[0] - 2 * radius, 0, sz[0], 2 * radius), (0, 0, 0))
64         draw.ellipse((sz[0] - 2 * radius, sz[1] - 2 * radius, sz[0], sz[1]), (0, 0, 0))
65         sticker.paste(
66             img,
67             (
68                 round(padding_x + (uw - img.size[0]) / 2), padding_y),
69             img
70         )
71         return sticker