pyblend2d 0.22.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pyblend2d-0.22.0/PKG-INFO +342 -0
- pyblend2d-0.22.0/README.md +302 -0
- pyblend2d-0.22.0/blend2d/__init__.py +290 -0
- pyblend2d-0.22.0/blend2d/_bin/blend2d_fx.lib +0 -0
- pyblend2d-0.22.0/blend2d/_bin/blend2d_geo.lib +0 -0
- pyblend2d-0.22.0/blend2d/_bin/blend2d_license.lib +0 -0
- pyblend2d-0.22.0/blend2d/_bin/blend2d_motion.lib +0 -0
- pyblend2d-0.22.0/blend2d/_bin/blend2d_perspective.lib +0 -0
- pyblend2d-0.22.0/blend2d/_bin/blend2d_video.lib +0 -0
- pyblend2d-0.22.0/blend2d/_bin/libblend2d.dll +0 -0
- pyblend2d-0.22.0/blend2d/_bin/libblend2d.so +0 -0
- pyblend2d-0.22.0/blend2d/_bin/libblend2d_fx.dll +0 -0
- pyblend2d-0.22.0/blend2d/_bin/libblend2d_fx.pdb +0 -0
- pyblend2d-0.22.0/blend2d/_bin/libblend2d_geo.dll +0 -0
- pyblend2d-0.22.0/blend2d/_bin/libblend2d_geo.pdb +0 -0
- pyblend2d-0.22.0/blend2d/_bin/libblend2d_license.dll +0 -0
- pyblend2d-0.22.0/blend2d/_bin/libblend2d_motion.dll +0 -0
- pyblend2d-0.22.0/blend2d/_bin/libblend2d_motion.pdb +0 -0
- pyblend2d-0.22.0/blend2d/_bin/libblend2d_perspective.dll +0 -0
- pyblend2d-0.22.0/blend2d/_bin/libblend2d_perspective.pdb +0 -0
- pyblend2d-0.22.0/blend2d/_bin/libblend2d_video.dll +0 -0
- pyblend2d-0.22.0/blend2d/_bin/libblend2d_video.pdb +0 -0
- pyblend2d-0.22.0/blend2d/color.py +202 -0
- pyblend2d-0.22.0/blend2d/context.py +1439 -0
- pyblend2d-0.22.0/blend2d/diagnostics.py +201 -0
- pyblend2d-0.22.0/blend2d/enums.py +272 -0
- pyblend2d-0.22.0/blend2d/ffi.py +1301 -0
- pyblend2d-0.22.0/blend2d/font.py +251 -0
- pyblend2d-0.22.0/blend2d/fx/__init__.py +55 -0
- pyblend2d-0.22.0/blend2d/fx/_ffi.py +74 -0
- pyblend2d-0.22.0/blend2d/fx/blur.py +39 -0
- pyblend2d-0.22.0/blend2d/fx/color_grade.py +73 -0
- pyblend2d-0.22.0/blend2d/fx/glitch.py +61 -0
- pyblend2d-0.22.0/blend2d/fx/glow.py +104 -0
- pyblend2d-0.22.0/blend2d/fx/lens.py +98 -0
- pyblend2d-0.22.0/blend2d/fx/pipeline.py +105 -0
- pyblend2d-0.22.0/blend2d/geometry.py +242 -0
- pyblend2d-0.22.0/blend2d/image.py +355 -0
- pyblend2d-0.22.0/blend2d/license.py +104 -0
- pyblend2d-0.22.0/blend2d/matrix.py +153 -0
- pyblend2d-0.22.0/blend2d/motion/__init__.py +74 -0
- pyblend2d-0.22.0/blend2d/motion/easing.py +410 -0
- pyblend2d-0.22.0/blend2d/motion/particles.py +345 -0
- pyblend2d-0.22.0/blend2d/motion/path_anim.py +303 -0
- pyblend2d-0.22.0/blend2d/motion/perspective.py +426 -0
- pyblend2d-0.22.0/blend2d/motion/scene.py +237 -0
- pyblend2d-0.22.0/blend2d/motion/timeline.py +208 -0
- pyblend2d-0.22.0/blend2d/path.py +582 -0
- pyblend2d-0.22.0/blend2d/py.typed +1 -0
- pyblend2d-0.22.0/blend2d/shapgeo.py +705 -0
- pyblend2d-0.22.0/blend2d/shapgeo_downloader.py +159 -0
- pyblend2d-0.22.0/blend2d/shapgeo_io.py +303 -0
- pyblend2d-0.22.0/blend2d/shapgeo_proj.py +242 -0
- pyblend2d-0.22.0/blend2d/style.py +210 -0
- pyblend2d-0.22.0/blend2d/svg.py +383 -0
- pyblend2d-0.22.0/blend2d/video.py +498 -0
- pyblend2d-0.22.0/blend2d-src/blend2d-version.py +23 -0
- pyblend2d-0.22.0/pyblend2d.egg-info/PKG-INFO +342 -0
- pyblend2d-0.22.0/pyblend2d.egg-info/SOURCES.txt +87 -0
- pyblend2d-0.22.0/pyblend2d.egg-info/dependency_links.txt +1 -0
- pyblend2d-0.22.0/pyblend2d.egg-info/requires.txt +13 -0
- pyblend2d-0.22.0/pyblend2d.egg-info/top_level.txt +4 -0
- pyblend2d-0.22.0/pyproject.toml +56 -0
- pyblend2d-0.22.0/setup.cfg +4 -0
- pyblend2d-0.22.0/setup.py +14 -0
- pyblend2d-0.22.0/tests/test_advanced.py +148 -0
- pyblend2d-0.22.0/tests/test_context.py +71 -0
- pyblend2d-0.22.0/tests/test_cross_module_integration.py +189 -0
- pyblend2d-0.22.0/tests/test_extreme_stress_and_benchmarks.py +255 -0
- pyblend2d-0.22.0/tests/test_font.py +51 -0
- pyblend2d-0.22.0/tests/test_fx.py +101 -0
- pyblend2d-0.22.0/tests/test_image.py +51 -0
- pyblend2d-0.22.0/tests/test_license.py +47 -0
- pyblend2d-0.22.0/tests/test_matrix.py +44 -0
- pyblend2d-0.22.0/tests/test_motion_easing.py +70 -0
- pyblend2d-0.22.0/tests/test_motion_particles.py +57 -0
- pyblend2d-0.22.0/tests/test_motion_path.py +73 -0
- pyblend2d-0.22.0/tests/test_motion_scene.py +47 -0
- pyblend2d-0.22.0/tests/test_motion_timeline.py +54 -0
- pyblend2d-0.22.0/tests/test_numpy_pil.py +45 -0
- pyblend2d-0.22.0/tests/test_path.py +58 -0
- pyblend2d-0.22.0/tests/test_perspective_camera.py +138 -0
- pyblend2d-0.22.0/tests/test_shapgeo.py +195 -0
- pyblend2d-0.22.0/tests/test_shapgeo_downloader.py +69 -0
- pyblend2d-0.22.0/tests/test_shapgeo_io.py +183 -0
- pyblend2d-0.22.0/tests/test_shapgeo_proj.py +86 -0
- pyblend2d-0.22.0/tests/test_style.py +53 -0
- pyblend2d-0.22.0/tests/test_v2_features.py +137 -0
- pyblend2d-0.22.0/tests/test_video.py +124 -0
|
@@ -0,0 +1,342 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pyblend2d
|
|
3
|
+
Version: 0.22.0
|
|
4
|
+
Summary: Ultra-Fast 2D/2.5D Vector Graphics, GIS, Motion & Video Engine for Python powered by Blend2D
|
|
5
|
+
Author: Islam Arifi, PyBlend Developers
|
|
6
|
+
Maintainer: Islam Arifi
|
|
7
|
+
License: Proprietary
|
|
8
|
+
Project-URL: Homepage, https://huggingface.co/ArifiIslam/PyBlend
|
|
9
|
+
Project-URL: Repository, https://huggingface.co/ArifiIslam/PyBlend
|
|
10
|
+
Project-URL: Documentation, https://huggingface.co/ArifiIslam/PyBlend/blob/main/DOCUMENTATION.md
|
|
11
|
+
Keywords: blend2d,graphics,2d,vector,rasterizer,jit,simd,motion,gis,geopandas,shapely,video,render,vfx
|
|
12
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: Topic :: Multimedia :: Graphics
|
|
15
|
+
Classifier: Topic :: Scientific/Engineering :: Visualization
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
23
|
+
Classifier: License :: Other/Proprietary License
|
|
24
|
+
Classifier: Operating System :: Microsoft :: Windows
|
|
25
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
26
|
+
Classifier: Operating System :: MacOS
|
|
27
|
+
Requires-Python: >=3.8
|
|
28
|
+
Description-Content-Type: text/markdown
|
|
29
|
+
Provides-Extra: numpy
|
|
30
|
+
Requires-Dist: numpy>=1.20; extra == "numpy"
|
|
31
|
+
Provides-Extra: pil
|
|
32
|
+
Requires-Dist: Pillow>=8.0; extra == "pil"
|
|
33
|
+
Provides-Extra: all
|
|
34
|
+
Requires-Dist: numpy>=1.20; extra == "all"
|
|
35
|
+
Requires-Dist: Pillow>=8.0; extra == "all"
|
|
36
|
+
Requires-Dist: geopandas>=0.10.0; extra == "all"
|
|
37
|
+
Requires-Dist: shapely>=1.8.0; extra == "all"
|
|
38
|
+
Requires-Dist: pytest>=7.0; extra == "all"
|
|
39
|
+
Dynamic: requires-python
|
|
40
|
+
|
|
41
|
+
# PyBlend (Blend2D for Python) ๐จ๐
|
|
42
|
+
|
|
43
|
+
[](https://www.python.org/)
|
|
44
|
+
[](https://huggingface.co/ArifiIslam/PyBlend)
|
|
45
|
+
[](https://blend2d.com)
|
|
46
|
+
|
|
47
|
+
**Author & Creator**: Islam Arifi
|
|
48
|
+
**PyPI Package**: [`pyblend2d`](https://pypi.org/project/pyblend2d/)
|
|
49
|
+
**Private Mirror**: [Hugging Face](https://huggingface.co/ArifiIslam/PyBlend)
|
|
50
|
+
|
|
51
|
+
**PyBlend** is an ultra-fast 2D/2.5D vector graphics, GIS, motion graphics, and cinematic video engine for Python powered by **[Blend2D](https://blend2d.com)** (embedded JIT compiler and SIMD hardware acceleration).
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## ๐ License Activation & Evaluation Mode
|
|
56
|
+
|
|
57
|
+
PyBlend is distributed under a **Proprietary Commercial License** with an Evaluation Mode.
|
|
58
|
+
Unlicensed evaluation renders include a subtle semi-transparent `"Auras"` watermark in the center.
|
|
59
|
+
|
|
60
|
+
### To Activate Full Commercial Version:
|
|
61
|
+
Call `blend2d.set_license()` at the beginning of your program:
|
|
62
|
+
|
|
63
|
+
```python
|
|
64
|
+
import blend2d
|
|
65
|
+
|
|
66
|
+
# Activate official license (removes all evaluation watermarks)
|
|
67
|
+
blend2d.set_license("08032008is")
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Or set the environment variable:
|
|
71
|
+
```bash
|
|
72
|
+
export PYBLEND_LICENSE_KEY="08032008is" # Linux/macOS
|
|
73
|
+
set PYBLEND_LICENSE_KEY="08032008is" # Windows
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
## ๐ฆ Official Installation
|
|
79
|
+
|
|
80
|
+
### 1. From PyPI (Recommended):
|
|
81
|
+
```bash
|
|
82
|
+
pip install pyblend2d
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### 2. Direct Wheel (from Hugging Face Mirror):
|
|
86
|
+
```bash
|
|
87
|
+
pip install "https://huggingface.co/ArifiIslam/PyBlend/resolve/main/dist/pyblend2d-0.21.2-py3-none-any.whl"
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### 3. Optional Speed & Ecosystem Extensions:
|
|
91
|
+
```bash
|
|
92
|
+
pip install "pyblend2d[numpy,pil]" # For Zero-Copy NumPy & Pillow integration
|
|
93
|
+
pip install "pyblend2d[all]" # For GeoPandas, Shapely & full testing
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### โ
Quick Verification:
|
|
97
|
+
```python
|
|
98
|
+
import blend2d
|
|
99
|
+
print(f"PyBlend Version: {blend2d.__version__} by {blend2d.__author__}")
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
---
|
|
103
|
+
|
|
104
|
+
## ๐ Quickstart
|
|
105
|
+
|
|
106
|
+
### 1. Basic Drawing & Context Manager
|
|
107
|
+
|
|
108
|
+
```python
|
|
109
|
+
from blend2d import Image, Context, Format
|
|
110
|
+
|
|
111
|
+
# Create 800x600 surface in PRGB32 format
|
|
112
|
+
img = Image(800, 600, Format.PRGB32)
|
|
113
|
+
|
|
114
|
+
with Context(img) as ctx:
|
|
115
|
+
# Fill background
|
|
116
|
+
ctx.fill_all("#0F172A")
|
|
117
|
+
|
|
118
|
+
# Draw smooth anti-aliased circles
|
|
119
|
+
ctx.fill_circle(200, 300, 100, "#3B82F6")
|
|
120
|
+
ctx.stroke_width = 4.0
|
|
121
|
+
ctx.stroke_circle(200, 300, 100, "#93C5FD")
|
|
122
|
+
|
|
123
|
+
# Draw rounded rectangle
|
|
124
|
+
ctx.fill_round_rect(400, 200, 300, 200, 24, "#10B981")
|
|
125
|
+
ctx.stroke_width = 3.0
|
|
126
|
+
ctx.stroke_round_rect(400, 200, 300, 200, 24, "#A7F3D0")
|
|
127
|
+
|
|
128
|
+
# Save directly to PNG
|
|
129
|
+
img.write_to_file("output.png")
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
---
|
|
133
|
+
|
|
134
|
+
### 2. Linear, Radial & Conic Gradients
|
|
135
|
+
|
|
136
|
+
```python
|
|
137
|
+
from blend2d import Image, Context, LinearGradient, RadialGradient, ConicGradient
|
|
138
|
+
|
|
139
|
+
img = Image(600, 400)
|
|
140
|
+
with Context(img) as ctx:
|
|
141
|
+
# Linear Gradient
|
|
142
|
+
grad = LinearGradient(50, 50, 550, 350)
|
|
143
|
+
grad.add_stop(0.0, "#EC4899")
|
|
144
|
+
grad.add_stop(0.5, "#8B5CF6")
|
|
145
|
+
grad.add_stop(1.0, "#06B6D4")
|
|
146
|
+
|
|
147
|
+
ctx.fill_round_rect(50, 50, 500, 300, 30, grad)
|
|
148
|
+
|
|
149
|
+
img.write_to_file("gradient.png")
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
---
|
|
153
|
+
|
|
154
|
+
### 3. Vector Paths & Bezier Curves
|
|
155
|
+
|
|
156
|
+
```python
|
|
157
|
+
from blend2d import Image, Context, Path
|
|
158
|
+
|
|
159
|
+
img = Image(400, 400)
|
|
160
|
+
with Context(img) as ctx:
|
|
161
|
+
ctx.fill_all("#18181B")
|
|
162
|
+
|
|
163
|
+
# Build vector path
|
|
164
|
+
p = Path()
|
|
165
|
+
p.move_to(50, 200)
|
|
166
|
+
p.cubic_to(150, 50, 250, 350, 350, 200)
|
|
167
|
+
p.close()
|
|
168
|
+
|
|
169
|
+
ctx.fill_path(p, "#38BDF833")
|
|
170
|
+
ctx.stroke_width = 3.0
|
|
171
|
+
ctx.stroke_path(p, "#38BDF8")
|
|
172
|
+
|
|
173
|
+
img.write_to_file("curve.png")
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
---
|
|
177
|
+
|
|
178
|
+
### 4. Typography & Font Metrics
|
|
179
|
+
|
|
180
|
+
```python
|
|
181
|
+
from blend2d import Image, Context, Font
|
|
182
|
+
|
|
183
|
+
img = Image(600, 200)
|
|
184
|
+
with Context(img) as ctx:
|
|
185
|
+
ctx.fill_all("#0B0F19")
|
|
186
|
+
|
|
187
|
+
font = Font.from_file("C:/Windows/Fonts/segoeui.ttf", 36.0)
|
|
188
|
+
|
|
189
|
+
# Measure text bounding box & advance
|
|
190
|
+
metrics = font.get_text_metrics("Hello Blend2D!")
|
|
191
|
+
print(f"Advance width: {metrics.advance.x}px")
|
|
192
|
+
|
|
193
|
+
ctx.fill_text(40, 110, font, "Hello Blend2D!", "#38BDF8")
|
|
194
|
+
|
|
195
|
+
img.write_to_file("text.png")
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
---
|
|
199
|
+
|
|
200
|
+
### 5. Zero-Copy NumPy Interoperability
|
|
201
|
+
|
|
202
|
+
```python
|
|
203
|
+
import numpy as np
|
|
204
|
+
from blend2d import Image, Context
|
|
205
|
+
|
|
206
|
+
img = Image(500, 500)
|
|
207
|
+
|
|
208
|
+
# Get direct pointer buffer view as NumPy array (no memory copy)
|
|
209
|
+
buf = img.to_numpy(copy=False)
|
|
210
|
+
|
|
211
|
+
# Modify pixels directly using vector math
|
|
212
|
+
y, x = np.mgrid[0:500, 0:500]
|
|
213
|
+
buf[:, :, 0] = (x % 256).astype(np.uint8) # Blue
|
|
214
|
+
buf[:, :, 1] = (y % 256).astype(np.uint8) # Green
|
|
215
|
+
buf[:, :, 2] = 128 # Red
|
|
216
|
+
buf[:, :, 3] = 255 # Alpha
|
|
217
|
+
|
|
218
|
+
# Render vector overlays on top of the NumPy buffer
|
|
219
|
+
with Context(img) as ctx:
|
|
220
|
+
ctx.stroke_width = 5.0
|
|
221
|
+
ctx.stroke_circle(250, 250, 150, "white")
|
|
222
|
+
|
|
223
|
+
img.write_to_file("numpy_blend.png")
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
---
|
|
227
|
+
|
|
228
|
+
### 6. Mass Bulk Array Operations (100,000+ Shapes in 1 Call)
|
|
229
|
+
|
|
230
|
+
Render massive GIS maps, scatter plots, and point clouds in a single C call with zero Python loop overhead:
|
|
231
|
+
|
|
232
|
+
```python
|
|
233
|
+
import numpy as np
|
|
234
|
+
from blend2d import Image, Context
|
|
235
|
+
|
|
236
|
+
img = Image(1000, 1000)
|
|
237
|
+
with Context(img) as ctx:
|
|
238
|
+
ctx.fill_all("#090D16")
|
|
239
|
+
|
|
240
|
+
# Generate 100,000 rectangles [x, y, w, h] as a float64 NumPy array
|
|
241
|
+
rects = np.random.uniform(0, 950, (100000, 4)).astype(np.float64)
|
|
242
|
+
|
|
243
|
+
# โก Single C call โ renders in ~30ms!
|
|
244
|
+
ctx.fill_rect_array(rects, "#38BDF822")
|
|
245
|
+
|
|
246
|
+
img.write_to_file("bulk_rectangles.png")
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
---
|
|
250
|
+
|
|
251
|
+
### 7. Typography to Vector Path Outlines
|
|
252
|
+
|
|
253
|
+
Convert shaped text (including multi-lingual and Arabic) directly into editable vector `Path` contours:
|
|
254
|
+
|
|
255
|
+
```python
|
|
256
|
+
from blend2d import Image, Context, Font, LinearGradient
|
|
257
|
+
|
|
258
|
+
img = Image(800, 200)
|
|
259
|
+
font = Font.from_file("C:/Windows/Fonts/segoeui.ttf", 48.0)
|
|
260
|
+
|
|
261
|
+
# Convert text string to vector bezier contours
|
|
262
|
+
text_path = font.get_text_outlines("PyBlend 2D Vector Outlines", origin=(40, 120))
|
|
263
|
+
|
|
264
|
+
with Context(img) as ctx:
|
|
265
|
+
ctx.fill_all("#0B0F19")
|
|
266
|
+
|
|
267
|
+
# Fill text with dynamic linear gradient
|
|
268
|
+
grad = LinearGradient(40, 0, 700, 0)
|
|
269
|
+
grad.add_stop(0.0, "#38BDF8")
|
|
270
|
+
grad.add_stop(1.0, "#F43F5E")
|
|
271
|
+
|
|
272
|
+
ctx.fill_path(text_path, grad)
|
|
273
|
+
ctx.stroke_width = 1.5
|
|
274
|
+
ctx.stroke_path(text_path, "#FFFFFF66")
|
|
275
|
+
|
|
276
|
+
img.write_to_file("vector_text.png")
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
---
|
|
280
|
+
|
|
281
|
+
### 8. Zero-Copy FFmpeg Streaming & Native Buffer Protocol
|
|
282
|
+
|
|
283
|
+
Stream raw frames directly to FFmpeg stdin or sockets with zero memory copies:
|
|
284
|
+
|
|
285
|
+
```python
|
|
286
|
+
import subprocess
|
|
287
|
+
from blend2d import Image, Context
|
|
288
|
+
|
|
289
|
+
img = Image(1920, 1080)
|
|
290
|
+
|
|
291
|
+
# Direct zero-copy memoryview
|
|
292
|
+
frame_buffer = img.buffer
|
|
293
|
+
|
|
294
|
+
# Example: Write directly to FFmpeg subprocess
|
|
295
|
+
# proc = subprocess.Popen(['ffmpeg', '-f', 'rawvideo', '-pix_fmt', 'bgra', ...], stdin=subprocess.PIPE)
|
|
296
|
+
# proc.stdin.write(frame_buffer)
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
---
|
|
300
|
+
|
|
301
|
+
## โ๏ธ Google Colab & Kaggle Support
|
|
302
|
+
|
|
303
|
+
PyBlend ships with pre-compiled Linux x86_64 JIT binaries (`libblend2d.so`), allowing instant execution on Colab and Kaggle without building from source:
|
|
304
|
+
|
|
305
|
+
```python
|
|
306
|
+
!pip install pyblend2d
|
|
307
|
+
import blend2d
|
|
308
|
+
print("Blend2D running with JIT & SIMD on Linux Cloud!")
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
---
|
|
312
|
+
|
|
313
|
+
## ๐งช Running the Test Suite
|
|
314
|
+
|
|
315
|
+
Run the full pytest suite:
|
|
316
|
+
|
|
317
|
+
```bash
|
|
318
|
+
python -m pytest tests -v
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
---
|
|
322
|
+
|
|
323
|
+
## ๐จ Running Examples
|
|
324
|
+
|
|
325
|
+
```bash
|
|
326
|
+
python examples/01_basic_shapes.py
|
|
327
|
+
python examples/02_gradients_and_patterns.py
|
|
328
|
+
python examples/03_vector_paths_and_bezier.py
|
|
329
|
+
python examples/04_typography_and_text.py
|
|
330
|
+
python examples/05_numpy_vector_overlay.py
|
|
331
|
+
python examples/06_composite_ops.py
|
|
332
|
+
python examples/07_bulk_gis_and_vector_text.py
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
Generated outputs will be placed in the `output/` directory.
|
|
336
|
+
|
|
337
|
+
---
|
|
338
|
+
|
|
339
|
+
## ๐ License
|
|
340
|
+
|
|
341
|
+
This library is licensed under the [Zlib License](LICENSE). Blend2D is licensed under the Zlib License.
|
|
342
|
+
|
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
# PyBlend (Blend2D for Python) ๐จ๐
|
|
2
|
+
|
|
3
|
+
[](https://www.python.org/)
|
|
4
|
+
[](https://huggingface.co/ArifiIslam/PyBlend)
|
|
5
|
+
[](https://blend2d.com)
|
|
6
|
+
|
|
7
|
+
**Author & Creator**: Islam Arifi
|
|
8
|
+
**PyPI Package**: [`pyblend2d`](https://pypi.org/project/pyblend2d/)
|
|
9
|
+
**Private Mirror**: [Hugging Face](https://huggingface.co/ArifiIslam/PyBlend)
|
|
10
|
+
|
|
11
|
+
**PyBlend** is an ultra-fast 2D/2.5D vector graphics, GIS, motion graphics, and cinematic video engine for Python powered by **[Blend2D](https://blend2d.com)** (embedded JIT compiler and SIMD hardware acceleration).
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## ๐ License Activation & Evaluation Mode
|
|
16
|
+
|
|
17
|
+
PyBlend is distributed under a **Proprietary Commercial License** with an Evaluation Mode.
|
|
18
|
+
Unlicensed evaluation renders include a subtle semi-transparent `"Auras"` watermark in the center.
|
|
19
|
+
|
|
20
|
+
### To Activate Full Commercial Version:
|
|
21
|
+
Call `blend2d.set_license()` at the beginning of your program:
|
|
22
|
+
|
|
23
|
+
```python
|
|
24
|
+
import blend2d
|
|
25
|
+
|
|
26
|
+
# Activate official license (removes all evaluation watermarks)
|
|
27
|
+
blend2d.set_license("08032008is")
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Or set the environment variable:
|
|
31
|
+
```bash
|
|
32
|
+
export PYBLEND_LICENSE_KEY="08032008is" # Linux/macOS
|
|
33
|
+
set PYBLEND_LICENSE_KEY="08032008is" # Windows
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## ๐ฆ Official Installation
|
|
39
|
+
|
|
40
|
+
### 1. From PyPI (Recommended):
|
|
41
|
+
```bash
|
|
42
|
+
pip install pyblend2d
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### 2. Direct Wheel (from Hugging Face Mirror):
|
|
46
|
+
```bash
|
|
47
|
+
pip install "https://huggingface.co/ArifiIslam/PyBlend/resolve/main/dist/pyblend2d-0.21.2-py3-none-any.whl"
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### 3. Optional Speed & Ecosystem Extensions:
|
|
51
|
+
```bash
|
|
52
|
+
pip install "pyblend2d[numpy,pil]" # For Zero-Copy NumPy & Pillow integration
|
|
53
|
+
pip install "pyblend2d[all]" # For GeoPandas, Shapely & full testing
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### โ
Quick Verification:
|
|
57
|
+
```python
|
|
58
|
+
import blend2d
|
|
59
|
+
print(f"PyBlend Version: {blend2d.__version__} by {blend2d.__author__}")
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## ๐ Quickstart
|
|
65
|
+
|
|
66
|
+
### 1. Basic Drawing & Context Manager
|
|
67
|
+
|
|
68
|
+
```python
|
|
69
|
+
from blend2d import Image, Context, Format
|
|
70
|
+
|
|
71
|
+
# Create 800x600 surface in PRGB32 format
|
|
72
|
+
img = Image(800, 600, Format.PRGB32)
|
|
73
|
+
|
|
74
|
+
with Context(img) as ctx:
|
|
75
|
+
# Fill background
|
|
76
|
+
ctx.fill_all("#0F172A")
|
|
77
|
+
|
|
78
|
+
# Draw smooth anti-aliased circles
|
|
79
|
+
ctx.fill_circle(200, 300, 100, "#3B82F6")
|
|
80
|
+
ctx.stroke_width = 4.0
|
|
81
|
+
ctx.stroke_circle(200, 300, 100, "#93C5FD")
|
|
82
|
+
|
|
83
|
+
# Draw rounded rectangle
|
|
84
|
+
ctx.fill_round_rect(400, 200, 300, 200, 24, "#10B981")
|
|
85
|
+
ctx.stroke_width = 3.0
|
|
86
|
+
ctx.stroke_round_rect(400, 200, 300, 200, 24, "#A7F3D0")
|
|
87
|
+
|
|
88
|
+
# Save directly to PNG
|
|
89
|
+
img.write_to_file("output.png")
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
### 2. Linear, Radial & Conic Gradients
|
|
95
|
+
|
|
96
|
+
```python
|
|
97
|
+
from blend2d import Image, Context, LinearGradient, RadialGradient, ConicGradient
|
|
98
|
+
|
|
99
|
+
img = Image(600, 400)
|
|
100
|
+
with Context(img) as ctx:
|
|
101
|
+
# Linear Gradient
|
|
102
|
+
grad = LinearGradient(50, 50, 550, 350)
|
|
103
|
+
grad.add_stop(0.0, "#EC4899")
|
|
104
|
+
grad.add_stop(0.5, "#8B5CF6")
|
|
105
|
+
grad.add_stop(1.0, "#06B6D4")
|
|
106
|
+
|
|
107
|
+
ctx.fill_round_rect(50, 50, 500, 300, 30, grad)
|
|
108
|
+
|
|
109
|
+
img.write_to_file("gradient.png")
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
### 3. Vector Paths & Bezier Curves
|
|
115
|
+
|
|
116
|
+
```python
|
|
117
|
+
from blend2d import Image, Context, Path
|
|
118
|
+
|
|
119
|
+
img = Image(400, 400)
|
|
120
|
+
with Context(img) as ctx:
|
|
121
|
+
ctx.fill_all("#18181B")
|
|
122
|
+
|
|
123
|
+
# Build vector path
|
|
124
|
+
p = Path()
|
|
125
|
+
p.move_to(50, 200)
|
|
126
|
+
p.cubic_to(150, 50, 250, 350, 350, 200)
|
|
127
|
+
p.close()
|
|
128
|
+
|
|
129
|
+
ctx.fill_path(p, "#38BDF833")
|
|
130
|
+
ctx.stroke_width = 3.0
|
|
131
|
+
ctx.stroke_path(p, "#38BDF8")
|
|
132
|
+
|
|
133
|
+
img.write_to_file("curve.png")
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
---
|
|
137
|
+
|
|
138
|
+
### 4. Typography & Font Metrics
|
|
139
|
+
|
|
140
|
+
```python
|
|
141
|
+
from blend2d import Image, Context, Font
|
|
142
|
+
|
|
143
|
+
img = Image(600, 200)
|
|
144
|
+
with Context(img) as ctx:
|
|
145
|
+
ctx.fill_all("#0B0F19")
|
|
146
|
+
|
|
147
|
+
font = Font.from_file("C:/Windows/Fonts/segoeui.ttf", 36.0)
|
|
148
|
+
|
|
149
|
+
# Measure text bounding box & advance
|
|
150
|
+
metrics = font.get_text_metrics("Hello Blend2D!")
|
|
151
|
+
print(f"Advance width: {metrics.advance.x}px")
|
|
152
|
+
|
|
153
|
+
ctx.fill_text(40, 110, font, "Hello Blend2D!", "#38BDF8")
|
|
154
|
+
|
|
155
|
+
img.write_to_file("text.png")
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
---
|
|
159
|
+
|
|
160
|
+
### 5. Zero-Copy NumPy Interoperability
|
|
161
|
+
|
|
162
|
+
```python
|
|
163
|
+
import numpy as np
|
|
164
|
+
from blend2d import Image, Context
|
|
165
|
+
|
|
166
|
+
img = Image(500, 500)
|
|
167
|
+
|
|
168
|
+
# Get direct pointer buffer view as NumPy array (no memory copy)
|
|
169
|
+
buf = img.to_numpy(copy=False)
|
|
170
|
+
|
|
171
|
+
# Modify pixels directly using vector math
|
|
172
|
+
y, x = np.mgrid[0:500, 0:500]
|
|
173
|
+
buf[:, :, 0] = (x % 256).astype(np.uint8) # Blue
|
|
174
|
+
buf[:, :, 1] = (y % 256).astype(np.uint8) # Green
|
|
175
|
+
buf[:, :, 2] = 128 # Red
|
|
176
|
+
buf[:, :, 3] = 255 # Alpha
|
|
177
|
+
|
|
178
|
+
# Render vector overlays on top of the NumPy buffer
|
|
179
|
+
with Context(img) as ctx:
|
|
180
|
+
ctx.stroke_width = 5.0
|
|
181
|
+
ctx.stroke_circle(250, 250, 150, "white")
|
|
182
|
+
|
|
183
|
+
img.write_to_file("numpy_blend.png")
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
---
|
|
187
|
+
|
|
188
|
+
### 6. Mass Bulk Array Operations (100,000+ Shapes in 1 Call)
|
|
189
|
+
|
|
190
|
+
Render massive GIS maps, scatter plots, and point clouds in a single C call with zero Python loop overhead:
|
|
191
|
+
|
|
192
|
+
```python
|
|
193
|
+
import numpy as np
|
|
194
|
+
from blend2d import Image, Context
|
|
195
|
+
|
|
196
|
+
img = Image(1000, 1000)
|
|
197
|
+
with Context(img) as ctx:
|
|
198
|
+
ctx.fill_all("#090D16")
|
|
199
|
+
|
|
200
|
+
# Generate 100,000 rectangles [x, y, w, h] as a float64 NumPy array
|
|
201
|
+
rects = np.random.uniform(0, 950, (100000, 4)).astype(np.float64)
|
|
202
|
+
|
|
203
|
+
# โก Single C call โ renders in ~30ms!
|
|
204
|
+
ctx.fill_rect_array(rects, "#38BDF822")
|
|
205
|
+
|
|
206
|
+
img.write_to_file("bulk_rectangles.png")
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
---
|
|
210
|
+
|
|
211
|
+
### 7. Typography to Vector Path Outlines
|
|
212
|
+
|
|
213
|
+
Convert shaped text (including multi-lingual and Arabic) directly into editable vector `Path` contours:
|
|
214
|
+
|
|
215
|
+
```python
|
|
216
|
+
from blend2d import Image, Context, Font, LinearGradient
|
|
217
|
+
|
|
218
|
+
img = Image(800, 200)
|
|
219
|
+
font = Font.from_file("C:/Windows/Fonts/segoeui.ttf", 48.0)
|
|
220
|
+
|
|
221
|
+
# Convert text string to vector bezier contours
|
|
222
|
+
text_path = font.get_text_outlines("PyBlend 2D Vector Outlines", origin=(40, 120))
|
|
223
|
+
|
|
224
|
+
with Context(img) as ctx:
|
|
225
|
+
ctx.fill_all("#0B0F19")
|
|
226
|
+
|
|
227
|
+
# Fill text with dynamic linear gradient
|
|
228
|
+
grad = LinearGradient(40, 0, 700, 0)
|
|
229
|
+
grad.add_stop(0.0, "#38BDF8")
|
|
230
|
+
grad.add_stop(1.0, "#F43F5E")
|
|
231
|
+
|
|
232
|
+
ctx.fill_path(text_path, grad)
|
|
233
|
+
ctx.stroke_width = 1.5
|
|
234
|
+
ctx.stroke_path(text_path, "#FFFFFF66")
|
|
235
|
+
|
|
236
|
+
img.write_to_file("vector_text.png")
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
---
|
|
240
|
+
|
|
241
|
+
### 8. Zero-Copy FFmpeg Streaming & Native Buffer Protocol
|
|
242
|
+
|
|
243
|
+
Stream raw frames directly to FFmpeg stdin or sockets with zero memory copies:
|
|
244
|
+
|
|
245
|
+
```python
|
|
246
|
+
import subprocess
|
|
247
|
+
from blend2d import Image, Context
|
|
248
|
+
|
|
249
|
+
img = Image(1920, 1080)
|
|
250
|
+
|
|
251
|
+
# Direct zero-copy memoryview
|
|
252
|
+
frame_buffer = img.buffer
|
|
253
|
+
|
|
254
|
+
# Example: Write directly to FFmpeg subprocess
|
|
255
|
+
# proc = subprocess.Popen(['ffmpeg', '-f', 'rawvideo', '-pix_fmt', 'bgra', ...], stdin=subprocess.PIPE)
|
|
256
|
+
# proc.stdin.write(frame_buffer)
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
---
|
|
260
|
+
|
|
261
|
+
## โ๏ธ Google Colab & Kaggle Support
|
|
262
|
+
|
|
263
|
+
PyBlend ships with pre-compiled Linux x86_64 JIT binaries (`libblend2d.so`), allowing instant execution on Colab and Kaggle without building from source:
|
|
264
|
+
|
|
265
|
+
```python
|
|
266
|
+
!pip install pyblend2d
|
|
267
|
+
import blend2d
|
|
268
|
+
print("Blend2D running with JIT & SIMD on Linux Cloud!")
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
---
|
|
272
|
+
|
|
273
|
+
## ๐งช Running the Test Suite
|
|
274
|
+
|
|
275
|
+
Run the full pytest suite:
|
|
276
|
+
|
|
277
|
+
```bash
|
|
278
|
+
python -m pytest tests -v
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
---
|
|
282
|
+
|
|
283
|
+
## ๐จ Running Examples
|
|
284
|
+
|
|
285
|
+
```bash
|
|
286
|
+
python examples/01_basic_shapes.py
|
|
287
|
+
python examples/02_gradients_and_patterns.py
|
|
288
|
+
python examples/03_vector_paths_and_bezier.py
|
|
289
|
+
python examples/04_typography_and_text.py
|
|
290
|
+
python examples/05_numpy_vector_overlay.py
|
|
291
|
+
python examples/06_composite_ops.py
|
|
292
|
+
python examples/07_bulk_gis_and_vector_text.py
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
Generated outputs will be placed in the `output/` directory.
|
|
296
|
+
|
|
297
|
+
---
|
|
298
|
+
|
|
299
|
+
## ๐ License
|
|
300
|
+
|
|
301
|
+
This library is licensed under the [Zlib License](LICENSE). Blend2D is licensed under the Zlib License.
|
|
302
|
+
|