11from __future__ import annotations
22
33from io import BytesIO
4+ from pathlib import Path
45from typing import List , Literal , Optional , Tuple , Union
56
6- from PIL import Image , ImageDraw , ImageFilter , ImageFont
7+ from PIL import Image as PilImage , ImageDraw , ImageFilter , ImageFont
8+ from PIL .Image import Image
79
810from .canvas import Canvas
911from .font import Font
@@ -16,19 +18,24 @@ class Editor:
1618
1719 Parameters
1820 ----------
19- image : Union[Image. Image, str, Editor, Canvas]
21+ _image : Union[Image, str, Editor, Canvas]
2022 Image or Canvas to edit.
2123 """
2224
2325 def __init__ (
24- self , image : Union [Image . Image , str , BytesIO , Editor , Canvas ]
26+ self , _image : Union [Image , str , BytesIO , Editor , Canvas ]
2527 ) -> None :
26- if isinstance (image , str ) or isinstance (image , BytesIO ):
27- self .image = Image .open (image ).convert ("RGBA" )
28- elif isinstance (image , Canvas ) or isinstance (image , Editor ):
29- self .image = image .image .convert ("RGBA" )
28+ if isinstance (_image , (str , BytesIO , Path )):
29+ self .image : Image = PilImage .open (_image )
30+ elif isinstance (_image , (Canvas , Editor )):
31+ self .image : Image = _image .image .convert ("RGBA" )
32+ elif isinstance (_image , Image ):
33+ self .image : Image = _image .convert ("RGBA" )
3034 else :
31- self .image = image .convert ("RGBA" )
35+ raise ValueError (
36+ "Editor requires an Image, Path, "
37+ "Editor or Canvas to start with"
38+ )
3239
3340 @property
3441 def image_bytes (self ) -> BytesIO :
@@ -56,7 +63,7 @@ def resize(self, size: Tuple[int, int], crop=False) -> Editor:
5663 Crop the image to bypass distortion, by default False
5764 """
5865 if not crop :
59- self .image = self .image .resize (size , Image .LANCZOS )
66+ self .image = self .image .resize (size , PilImage .LANCZOS )
6067
6168 else :
6269 width , height = self .image .size
@@ -75,7 +82,7 @@ def resize(self, size: Tuple[int, int], crop=False) -> Editor:
7582 resize = (0 , offset , width , height - offset )
7683
7784 self .image = self .image .crop (resize ).resize (
78- (ideal_width , ideal_height ), Image .LANCZOS
85+ (ideal_width , ideal_height ), PilImage .LANCZOS
7986 )
8087
8188 return self
@@ -90,13 +97,13 @@ def rounded_corners(self, radius: int = 10, offset: int = 2) -> Editor:
9097 offset : int, optional
9198 Offset pixel while making rounded, by default 2
9299 """
93- background = Image .new (
100+ background = PilImage .new (
94101 "RGBA" , size = self .image .size , color = (255 , 255 , 255 , 0 )
95102 )
96- holder = Image .new (
103+ holder = PilImage .new (
97104 "RGBA" , size = self .image .size , color = (255 , 255 , 255 , 0 )
98105 )
99- mask = Image .new (
106+ mask = PilImage .new (
100107 "RGBA" , size = self .image .size , color = (255 , 255 , 255 , 0 )
101108 )
102109 mask_draw = ImageDraw .Draw (mask )
@@ -107,26 +114,26 @@ def rounded_corners(self, radius: int = 10, offset: int = 2) -> Editor:
107114 fill = "black" ,
108115 )
109116 holder .paste (self .image , (0 , 0 ))
110- self .image = Image .composite (holder , background , mask )
117+ self .image = PilImage .composite (holder , background , mask )
111118
112119 return self
113120
114121 def circle_image (self ) -> Editor :
115122 """Make image circle"""
116- background = Image .new (
123+ background = PilImage .new (
117124 "RGBA" , size = self .image .size , color = (255 , 255 , 255 , 0 )
118125 )
119- holder = Image .new (
126+ holder = PilImage .new (
120127 "RGBA" , size = self .image .size , color = (255 , 255 , 255 , 0 )
121128 )
122- mask = Image .new (
129+ mask = PilImage .new (
123130 "RGBA" , size = self .image .size , color = (255 , 255 , 255 , 0 )
124131 )
125132 mask_draw = ImageDraw .Draw (mask )
126133 ellipse_size = tuple (i - 1 for i in self .image .size )
127134 mask_draw .ellipse ((0 , 0 ) + ellipse_size , fill = "black" )
128135 holder .paste (self .image , (0 , 0 ))
129- self .image = Image .composite (holder , background , mask )
136+ self .image = PilImage .composite (holder , background , mask )
130137
131138 return self
132139
@@ -136,28 +143,28 @@ def rotate(self, deg: float = 0, expand: bool = False) -> Editor:
136143 Parameters
137144 ----------
138145 deg : float, optional
139- Degress to rotate, by default 0
146+ Degrees to rotate, by default 0
140147 expand : bool, optional
141148 Expand while rotating, by default False
142149 """
143- self .image = self .image .rotate (angle = deg , expand = expand )
150+ self .image = self .image .rotate (deg , expand = expand )
144151 return self
145152
146153 def blur (
147- self , mode : Literal ["box" , "gussian " ] = "gussian " , amount : float = 1
154+ self , mode : Literal ["box" , "gaussian " ] = "gaussian " , amount : float = 1
148155 ) -> Editor :
149156 """Blur image
150157
151158 Parameters
152159 ----------
153- mode : Literal["box", "gussian "], optional
154- Blur mode, by default "gussian "
160+ mode : Literal["box", "gaussian "], optional
161+ Blur mode, by default "gaussian "
155162 amount : float, optional
156163 Amount of blur, by default 1
157164 """
158165 if mode == "box" :
159166 self .image = self .image .filter (ImageFilter .BoxBlur (radius = amount ))
160- if mode == "gussian " :
167+ if mode == "gaussian " :
161168 self .image = self .image .filter (
162169 ImageFilter .GaussianBlur (radius = amount )
163170 )
@@ -166,15 +173,15 @@ def blur(
166173
167174 def blend (
168175 self ,
169- image : Union [Image . Image , Editor , Canvas ],
176+ image : Union [Image , Editor , Canvas ],
170177 alpha : float = 0.0 ,
171178 on_top : bool = False ,
172179 ) -> Editor :
173180 """Blend image into editor image
174181
175182 Parameters
176183 ----------
177- image : Union[Image.Image , Editor, Canvas]
184+ image : Union[Image, Editor, Canvas]
178185 Image to blend
179186 alpha : float, optional
180187 Alpha amount, by default 0.0
@@ -188,35 +195,35 @@ def blend(
188195 image = Editor (image ).resize (self .image .size , crop = True ).image
189196
190197 if on_top :
191- self .image = Image .blend (self .image , image , alpha = alpha )
198+ self .image = PilImage .blend (self .image , image , alpha = alpha )
192199 else :
193- self .image = Image .blend (image , self .image , alpha = alpha )
200+ self .image = PilImage .blend (image , self .image , alpha = alpha )
194201
195202 return self
196203
197204 def paste (
198205 self ,
199- image : Union [Image . Image , Editor , Canvas ],
206+ image : Union [Image , Editor , Canvas ],
200207 position : Tuple [int , int ],
201208 ) -> Editor :
202209 """Paste image into editor
203210
204211 Parameters
205212 ----------
206- image : Union[Image.Image , Editor, Canvas]
213+ image : Union[Image, Editor, Canvas]
207214 Image to paste
208215 position : Tuple[float, float]
209216 Position to paste
210217 """
211- blank = Image .new (
218+ blank = PilImage .new (
212219 "RGBA" , size = self .image .size , color = (255 , 255 , 255 , 0 )
213220 )
214221
215222 if isinstance (image , Editor ) or isinstance (image , Canvas ):
216223 image = image .image
217224
218225 blank .paste (image , position )
219- self .image = Image .alpha_composite (self .image , blank )
226+ self .image = PilImage .alpha_composite (self .image , blank )
220227
221228 return self
222229
@@ -235,7 +242,7 @@ def text(
235242 Parameters
236243 ----------
237244 position : Tuple[float, float]
238- Position to draw text
245+ Position to draw text.
239246 text : str
240247 Text to draw
241248 font : Union[ImageFont.FreeTypeFont, Font], optional
@@ -345,7 +352,7 @@ def rectangle(
345352 Parameters
346353 ----------
347354 position : Tuple[float, float]
348- Position to draw recangle
355+ Position to draw rectangle
349356 width : float
350357 Width of rectangle
351358 height : float
@@ -410,7 +417,7 @@ def bar(
410417 height : Union[int, float]
411418 Height of the bar
412419 percentage : int, optional
413- Percebtage to fill of the bar, by default 1
420+ Percentage to fill of the bar, by default 1
414421 fill : Color, optional
415422 Fill color, by default None
416423 color : Color, optional
@@ -471,7 +478,7 @@ def rounded_bar(
471478 height : Union[int, float]
472479 Height of the bar
473480 percentage : float
474- Percentage to fill
481+ Percentage to fill.
475482 fill : Color, optional
476483 Fill color, by default None
477484 color : Color, optional
@@ -544,7 +551,7 @@ def ellipse(
544551
545552 def polygon (
546553 self ,
547- cordinates : list ,
554+ coordinates : list ,
548555 fill : Optional [Color ] = None ,
549556 color : Optional [Color ] = None ,
550557 outline : Optional [Color ] = None ,
@@ -553,8 +560,8 @@ def polygon(
553560
554561 Parameters
555562 ----------
556- cordinates : list
557- Cordinates to draw
563+ coordinates : list
564+ Coordinates to draw
558565 fill : Color, optional
559566 Fill color, by default None
560567 color : Color, optional
@@ -566,7 +573,7 @@ def polygon(
566573 fill = color
567574
568575 draw = ImageDraw .Draw (self .image )
569- draw .polygon (cordinates , fill = fill , outline = outline )
576+ draw .polygon (coordinates , fill = fill , outline = outline )
570577
571578 return self
572579
@@ -594,7 +601,7 @@ def arc(
594601 start : float
595602 Start position of arch
596603 rotation : float
597- Rotation in degre
604+ Rotation in degree
598605 fill : Color, optional
599606 Fill color, by default None
600607 color : Color, optional
@@ -624,14 +631,14 @@ def show(self):
624631 """Show the image."""
625632 self .image .show ()
626633
627- def save (self , fp , format : Optional [str ] = None , ** params ):
634+ def save (self , fp , file_format : Optional [str ] = None , ** params ):
628635 """Save the image
629636
630637 Parameters
631638 ----------
632639 fp : str
633640 File path
634- format : str, optional
641+ file_format : str, optional
635642 File format, by default None
636643 """
637- self .image .save (fp , format , ** params )
644+ self .image .save (fp , file_format , ** params )
0 commit comments