Skip to content

Commit 99d58b8

Browse files
committed
0.0.10
1 parent baef382 commit 99d58b8

File tree

12 files changed

+184
-127
lines changed

12 files changed

+184
-127
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# PyImageCUDA 0.0.9
1+
# PyImageCUDA 0.0.10
22

33
[![PyPI version](https://img.shields.io/pypi/v/pyimagecuda.svg)](https://pypi.org/project/pyimagecuda/)
44
[![Build Status](https://github.com/offerrall/pyimagecuda/actions/workflows/build.yml/badge.svg)](https://github.com/offerrall/pyimagecuda/actions)

docs/image.md

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -144,24 +144,14 @@ from pyimagecuda import Image
144144
img = Image(1920, 1080)
145145

146146
# Can logically resize within capacity
147-
img.width = 1280
148-
img.height = 720
147+
img.resize(1280, 720)
149148

150149
# Check capacity
151-
max_w, max_h = img.get_max_capacity()
152-
print(f"Capacity: {max_w}×{max_h}") # 1920×1080
150+
max_pixels = img.get_max_capacity()
151+
print(f"Capacity: {max_pixels:,} pixels") # 2,073,600 pixels (1920×1080)
153152
print(f"Current: {img.width}×{img.height}") # 1280×720
154153
```
155154

156-
Use case: Loading variable-sized images into fixed buffers.
157-
```python
158-
buffer = Image(4096, 4096) # Max capacity
159-
160-
for filename in images:
161-
load(filename, f32_buffer=buffer) # Adjusts buffer dimensions
162-
process(buffer)
163-
```
164-
165155
---
166156

167157
## Best Practices

pyimagecuda/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import ctypes
22
import sys
33

4-
__version__ = "0.0.9"
4+
__version__ = "0.0.10"
55

66
def _check_nvidia_driver():
77
try:

pyimagecuda/effect.py

Lines changed: 89 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
from .filter import Filter
55
from .blend import Blend
66
from .fill import Fill
7-
from .utils import ensure_capacity
87
from .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,

pyimagecuda/filter.py

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
from .image import Image
2-
from .utils import ensure_capacity
32
from .io import copy
4-
from .pyimagecuda_internal import (gaussian_blur_separable_f32, #type: ignore
5-
sharpen_f32,
6-
sepia_f32,
7-
invert_f32,
8-
threshold_f32,
9-
solarize_f32,
10-
filter_sobel_f32,
11-
filter_emboss_f32)
3+
from .pyimagecuda_internal import ( #type: ignore
4+
gaussian_blur_separable_f32,
5+
sharpen_f32,
6+
sepia_f32,
7+
invert_f32,
8+
threshold_f32,
9+
solarize_f32,
10+
filter_sobel_f32,
11+
filter_emboss_f32
12+
)
1213

1314

1415
class Filter:
@@ -43,14 +44,14 @@ def gaussian_blur(
4344
dst_buffer = Image(src.width, src.height)
4445
return_dst = True
4546
else:
46-
ensure_capacity(dst_buffer, src.width, src.height)
47+
dst_buffer.resize(src.width, src.height)
4748
return_dst = False
4849

4950
if temp_buffer is None:
5051
temp_buffer = Image(src.width, src.height)
5152
owns_temp = True
5253
else:
53-
ensure_capacity(temp_buffer, src.width, src.height)
54+
temp_buffer.resize(src.width, src.height)
5455
owns_temp = False
5556

5657
gaussian_blur_separable_f32(
@@ -93,7 +94,7 @@ def sharpen(
9394
dst_buffer = Image(src.width, src.height)
9495
return_buffer = True
9596
else:
96-
ensure_capacity(dst_buffer, src.width, src.height)
97+
dst_buffer.resize(src.width, src.height)
9798
return_buffer = False
9899

99100
sharpen_f32(
@@ -157,7 +158,7 @@ def sobel(src: Image, dst_buffer: Image | None = None) -> Image | None:
157158
dst_buffer = Image(src.width, src.height)
158159
return_buffer = True
159160
else:
160-
ensure_capacity(dst_buffer, src.width, src.height)
161+
dst_buffer.resize(src.width, src.height)
161162
return_buffer = False
162163

163164
filter_sobel_f32(
@@ -187,7 +188,7 @@ def emboss(src: Image, strength: float = 1.0, dst_buffer: Image | None = None) -
187188
dst_buffer = Image(src.width, src.height)
188189
return_buffer = True
189190
else:
190-
ensure_capacity(dst_buffer, src.width, src.height)
191+
dst_buffer.resize(src.width, src.height)
191192
return_buffer = False
192193

193194
filter_emboss_f32(

0 commit comments

Comments
 (0)