Cope 2.5.0
My personal "standard library" of all the generally useful code I've written for various projects over the years
Loading...
Searching...
No Matches
meme.py
1from .imports import try_import
2from io import BytesIO
3from importlib import resources as impresources
4from . import assets
5
6
7def look_at_this_graph(graph, fudge=(0, 28)):
8 """ LOOK AT THIS _____GRAPH!!! """
9 from PIL import Image
10 from PIL import ImageOps
11 matplotlib = try_import('matplotlib')
12 plotly = try_import('plotly')
13
14 template = Image.open(impresources.files(assets) / 'look at this photograph template.png')
15 mask = Image.open(impresources.files(assets) / 'look at this photograph mask.png').convert('L')
16
17 if matplotlib and isinstance(graph, matplotlib.figure.Figure):
18 graph.canvas.draw()
19 raw_graph = Image.frombytes('RGB', graph.canvas.get_width_height(), graph.canvas.tostring_rgb())
20 elif type(graph) is str:
21 try:
22 raw_graph = Image.open(graph)
23 except:
24 raise ValueError(f"Can't open file {graph}")
25 elif type(graph) is bytes:
26 raw_graph = Image.open(BytesIO(graph))
27 elif plotly and type(graph) is plotly.graph_objs._figure.Figure:
28 raw_graph = Image.open(BytesIO(plotly.io.to_image(graph, 'png', width=template.width, height=template.height)))
29 else:
30 raise ValueError(f"Graph type `{type(graph)}` not supported. Supported types are matplotlib, plotly, bytes, and filepaths")
31
32 # Resize, pad, rotate, and shift the graph
33 new_size = template.size
34 padding_color = (255, 255, 255)
35 graph_size = (343, 213)
36
37 raw_graph = raw_graph.resize(graph_size)
38
39 # Resize and pad the image
40 resized_image = ImageOps.expand(raw_graph, (
41 (new_size[0] - raw_graph.width) // 2,
42 (new_size[1] - raw_graph.height) // 2
43 ),
44 fill=padding_color
45 )
46
47 # In degrees
48 rotation_angle = 13.3
49
50 # Rotate the original image
51 rotated_image = raw_graph.rotate(rotation_angle, expand=True, fillcolor=padding_color)
52
53 # Calculate the shift
54 shift = (476 + fudge[0], 247 - (round(graph_size[1]/2)) + fudge[1])
55
56 # Create a new image with the padded size
57 adj_graph = Image.new("RGB", new_size, padding_color)
58
59 # Paste the rotated image onto the final image with the desired shift
60 adj_graph.paste(rotated_image, shift)
61 adj_graph
62
63 return Image.composite(adj_graph, template, mask)