44from .filter import Filter
55from .blend import Blend
66from .fill import Fill
7- from .utils import ensure_capacity
87from .pyimagecuda_internal import ( #type: ignore
98 rounded_corners_f32 ,
109 extract_alpha_f32 ,
@@ -25,15 +24,19 @@ def rounded_corners(image: Image, radius: float) -> None:
2524 Docs & Examples: https://offerrall.github.io/pyimagecuda/effect/#rounded_corners
2625 """
2726 max_radius = min (image .width , image .height ) / 2.0
28- if radius < 0 : raise ValueError ("Radius must be non-negative" )
29- if radius == 0 : return
30- if radius > max_radius : radius = max_radius
27+ if radius < 0 :
28+ raise ValueError ("Radius must be non-negative" )
29+ if radius == 0 :
30+ return
31+ if radius > max_radius :
32+ radius = max_radius
3133
3234 rounded_corners_f32 (image ._buffer ._handle , image .width , image .height , float (radius ))
3335
3436 @staticmethod
3537 def drop_shadow (
36- image : Image , offset_x : int = 10 ,
38+ image : Image ,
39+ offset_x : int = 10 ,
3740 offset_y : int = 10 ,
3841 blur : int = 20 ,
3942 color : tuple [float , float , float , float ] = (0.0 , 0.0 , 0.0 , 0.5 ),
@@ -52,42 +55,60 @@ def drop_shadow(
5255 pad_r = blur + max (0 , offset_x )
5356 pad_t = blur + max (0 , - offset_y )
5457 pad_b = blur + max (0 , offset_y )
55- res_w , res_h = image .width + pad_l + pad_r , image .height + pad_t + pad_b
56- img_x , img_y = pad_l , pad_t
58+ res_w = image .width + pad_l + pad_r
59+ res_h = image .height + pad_t + pad_b
60+ img_x = pad_l
61+ img_y = pad_t
5762 else :
58- res_w , res_h = image .width , image .height
59- img_x , img_y = 0 , 0
63+ res_w = image .width
64+ res_h = image .height
65+ img_x = 0
66+ img_y = 0
6067
6168 if dst_buffer is None :
62- result = Image (res_w , res_h ); ret = True
69+ result = Image (res_w , res_h )
70+ ret = True
6371 else :
64- ensure_capacity (dst_buffer , res_w , res_h ); result = dst_buffer ; ret = False
72+ dst_buffer .resize (res_w , res_h )
73+ result = dst_buffer
74+ ret = False
6575
6676 if shadow_buffer is None :
67- shadow = Image (res_w , res_h ); own_shadow = True
77+ shadow = Image (res_w , res_h )
78+ own_shadow = True
6879 else :
69- ensure_capacity (shadow_buffer , res_w , res_h ); shadow = shadow_buffer ; own_shadow = False
80+ shadow_buffer .resize (res_w , res_h )
81+ shadow = shadow_buffer
82+ own_shadow = False
7083
7184 if expand :
72- if temp_buffer is None : temp = Image (res_w , res_h )
73- else : ensure_capacity (temp_buffer , res_w , res_h ); temp = temp_buffer
74- Fill .color (shadow , (0 ,0 ,0 ,0 ))
75- temp .width , temp .height = image .width , image .height
85+ if temp_buffer is None :
86+ temp = Image (res_w , res_h )
87+ else :
88+ temp_buffer .resize (res_w , res_h )
89+ temp = temp_buffer
90+
91+ Fill .color (shadow , (0 , 0 , 0 , 0 ))
92+ temp .resize (image .width , image .height )
7693 extract_alpha_f32 (image ._buffer ._handle , temp ._buffer ._handle , image .width , image .height )
7794 Blend .normal (shadow , temp , anchor = 'top-left' , offset_x = pad_l , offset_y = pad_t )
78- if temp_buffer is None : temp .free ()
95+
96+ if temp_buffer is None :
97+ temp .free ()
7998 else :
8099 extract_alpha_f32 (image ._buffer ._handle , shadow ._buffer ._handle , image .width , image .height )
81100
82101 if blur > 0 :
83102 Filter .gaussian_blur (shadow , radius = blur , sigma = blur / 3.0 , dst_buffer = shadow )
84103
85104 colorize_alpha_mask_f32 (shadow ._buffer ._handle , shadow .width , shadow .height , color )
86- Fill .color (result , (0 ,0 , 0 , 0 ))
105+ Fill .color (result , (0 , 0 , 0 , 0 ))
87106 Blend .normal (result , shadow , anchor = 'top-left' , offset_x = offset_x , offset_y = offset_y )
88107 Blend .normal (result , image , anchor = 'top-left' , offset_x = img_x , offset_y = img_y )
89108
90- if own_shadow : shadow .free ()
109+ if own_shadow :
110+ shadow .free ()
111+
91112 return result if ret else None
92113
93114 @staticmethod
@@ -105,38 +126,66 @@ def stroke(
105126
106127 Docs & Examples: https://offerrall.github.io/pyimagecuda/effect/#stroke
107128 """
108- if width < 1 or width > 1000 : raise ValueError ("Invalid stroke width" )
109- if position not in ('outside' , 'inside' ): raise ValueError ("Invalid position" )
129+ if width < 1 or width > 1000 :
130+ raise ValueError ("Invalid stroke width" )
131+ if position not in ('outside' , 'inside' ):
132+ raise ValueError ("Invalid position" )
110133
111134 if position == 'outside' and expand :
112- res_w , res_h = image .width + width * 2 , image .height + width * 2
113- off_x , off_y = width , width
135+ res_w = image .width + width * 2
136+ res_h = image .height + width * 2
137+ off_x = width
138+ off_y = width
114139 else :
115- res_w , res_h = image .width , image .height
116- off_x , off_y = 0 , 0
140+ res_w = image .width
141+ res_h = image .height
142+ off_x = 0
143+ off_y = 0
117144
118145 if dst_buffer is None :
119- result = Image (res_w , res_h ); ret = True
146+ result = Image (res_w , res_h )
147+ ret = True
120148 else :
121- ensure_capacity (dst_buffer , res_w , res_h ); result = dst_buffer ; ret = False
149+ dst_buffer .resize (res_w , res_h )
150+ result = dst_buffer
151+ ret = False
122152
123153 if distance_buffer is None :
124- distance = Image (res_w , res_h ); own_dist = True
154+ distance = Image (res_w , res_h )
155+ own_dist = True
125156 else :
126- ensure_capacity (distance_buffer , res_w , res_h ); distance = distance_buffer ; own_dist = False
157+ distance_buffer .resize (res_w , res_h )
158+ distance = distance_buffer
159+ own_dist = False
127160
128161 compute_distance_field_f32 (
129- image ._buffer ._handle , distance ._buffer ._handle ,
130- image .width , image .height , res_w , res_h , off_x , off_y
162+ image ._buffer ._handle ,
163+ distance ._buffer ._handle ,
164+ image .width ,
165+ image .height ,
166+ res_w ,
167+ res_h ,
168+ off_x ,
169+ off_y
131170 )
132171
133172 generate_stroke_composite_f32 (
134- image ._buffer ._handle , distance ._buffer ._handle , result ._buffer ._handle ,
135- image .width , image .height , res_w , res_h , off_x , off_y ,
136- float (width ), color , 0 if position == 'outside' else 1
173+ image ._buffer ._handle ,
174+ distance ._buffer ._handle ,
175+ result ._buffer ._handle ,
176+ image .width ,
177+ image .height ,
178+ res_w ,
179+ res_h ,
180+ off_x ,
181+ off_y ,
182+ float (width ),
183+ color ,
184+ 0 if position == 'outside' else 1
137185 )
138186
139- if own_dist : distance .free ()
187+ if own_dist :
188+ distance .free ()
140189
141190 return result if ret else None
142191
@@ -152,8 +201,10 @@ def vignette(
152201
153202 Docs & Examples: https://offerrall.github.io/pyimagecuda/effect/#vignette
154203 """
155- if radius < 0 : radius = 0.0
156- if softness < 0 : softness = 0.0
204+ if radius < 0 :
205+ radius = 0.0
206+ if softness < 0 :
207+ softness = 0.0
157208
158209 effect_vignette_f32 (
159210 image ._buffer ._handle ,
0 commit comments