5
5
6
6
from __future__ import annotations
7
7
8
+ from typing import Union
9
+
8
10
import numpy as np
9
11
import PIL
12
+ from PIL import ImageFont
10
13
11
14
from .primitive import Primitive
12
15
@@ -18,11 +21,18 @@ class Overlay(Primitive):
18
21
19
22
Args:
20
23
image (PIL.Image | np.ndarray): Image to be overlaid.
24
+ label (str | None): Optional label name to overlay.
21
25
opacity (float): Opacity of the overlay.
22
26
"""
23
27
24
- def __init__ (self , image : PIL .Image | np .ndarray , opacity : float = 0.4 ) -> None :
28
+ def __init__ (
29
+ self ,
30
+ image : PIL .Image | np .ndarray ,
31
+ opacity : float = 0.4 ,
32
+ label : Union [str , None ] = None ,
33
+ ) -> None :
25
34
self .image = self ._to_pil (image )
35
+ self .label = label
26
36
self .opacity = opacity
27
37
28
38
def _to_pil (self , image : PIL .Image | np .ndarray ) -> PIL .Image :
@@ -33,3 +43,22 @@ def _to_pil(self, image: PIL.Image | np.ndarray) -> PIL.Image:
33
43
def compute (self , image : PIL .Image ) -> PIL .Image :
34
44
image_ = self .image .resize (image .size )
35
45
return PIL .Image .blend (image , image_ , self .opacity )
46
+
47
+ @classmethod
48
+ def overlay_labels (cls , image : PIL .Image , labels : Union [list [str ], str , None ] = None ) -> PIL .Image :
49
+ """Draw labels at the bottom center of the image.
50
+
51
+ This is handy when you want to add a label to the image.
52
+ """
53
+ if labels is not None :
54
+ labels = [labels ] if isinstance (labels , str ) else labels
55
+ font = ImageFont .load_default (size = 18 )
56
+ buffer_y = 5
57
+ dummy_image = PIL .Image .new ("RGB" , (1 , 1 ))
58
+ draw = PIL .ImageDraw .Draw (dummy_image )
59
+ textbox = draw .textbbox ((0 , 0 ), ", " .join (labels ), font = font )
60
+ image_ = PIL .Image .new ("RGB" , (textbox [2 ] - textbox [0 ], textbox [3 ] + buffer_y - textbox [1 ]), "white" )
61
+ draw = PIL .ImageDraw .Draw (image_ )
62
+ draw .text ((0 , 0 ), ", " .join (labels ), font = font , fill = "black" )
63
+ image .paste (image_ , (image .width // 2 - image_ .width // 2 , image .height - image_ .height - buffer_y ))
64
+ return image
0 commit comments