Fixes rotated image
[librarian.git] / src / librarian / covers / widgets / background.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 io
5 import time
6 from urllib.request import urlopen
7 import PIL.Image
8 from PIL import ImageOps
9 from .base import Widget
10
11
12 class Background(Widget):
13     transparency = False
14
15     def __init__(self, cover, crop_to_square=True):
16         self.crop_to_square = crop_to_square
17         super().__init__(cover)
18
19     def setup(self):
20         self.img = None
21         if self.cover.book_info.cover_url:
22             while True:
23                 try:
24                     data = io.BytesIO(urlopen(self.cover.book_info.cover_url, timeout=3).read())
25                 except:
26                     time.sleep(2)
27                 else:
28                     break
29                 
30             img = PIL.Image.open(data)
31             img = ImageOps.exif_transpose(img)
32
33             if self.crop_to_square:
34                 # crop top square.
35                 if img.size[1] > img.size[0]:
36                     img = img.crop((0, 0, img.size[0], img.size[0]))
37                 else:
38                     left = round((img.size[0] - img.size[1])/2)
39                     img = img.crop((
40                         left,
41                         0,
42                         left + img.size[1],
43                         img.size[1]
44                     ))
45             self.img = img
46
47     def build(self, w, h):
48         if not self.img:
49             return
50         img = self.img
51         scale = max(
52             w / img.size[0],
53             h / img.size[1]
54         )
55         img = self.img.resize((
56             round(scale * img.size[0]),
57             round(scale * img.size[1]),
58         ))
59         img = img.crop((
60             int((img.size[0] - w) / 2),
61             0,
62             w + int((img.size[0] - w) / 2),
63             h))
64         
65         return img