thorvg-python 1.0.0__tar.gz → 1.0.1__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.
- {thorvg_python-1.0.0/src/thorvg_python.egg-info → thorvg_python-1.0.1}/PKG-INFO +120 -1
- {thorvg_python-1.0.0 → thorvg_python-1.0.1}/pyproject.toml +3 -3
- {thorvg_python-1.0.0 → thorvg_python-1.0.1}/setup.py +4 -4
- {thorvg_python-1.0.0 → thorvg_python-1.0.1}/src/thorvg_python/__init__.py +1 -1
- {thorvg_python-1.0.0 → thorvg_python-1.0.1}/src/thorvg_python/animation/lottie.py +6 -4
- {thorvg_python-1.0.0 → thorvg_python-1.0.1}/src/thorvg_python/engine.py +16 -10
- {thorvg_python-1.0.0 → thorvg_python-1.0.1}/src/thorvg_python/paint/picture.py +5 -3
- {thorvg_python-1.0.0 → thorvg_python-1.0.1}/src/thorvg_python/paint/text.py +9 -6
- {thorvg_python-1.0.0 → thorvg_python-1.0.1}/src/thorvg_python/saver.py +2 -1
- {thorvg_python-1.0.0 → thorvg_python-1.0.1/src/thorvg_python.egg-info}/PKG-INFO +120 -1
- {thorvg_python-1.0.0 → thorvg_python-1.0.1}/tests/test_all.py +10 -1
- {thorvg_python-1.0.0 → thorvg_python-1.0.1}/LICENSE +0 -0
- {thorvg_python-1.0.0 → thorvg_python-1.0.1}/MANIFEST.in +0 -0
- {thorvg_python-1.0.0 → thorvg_python-1.0.1}/README.md +0 -0
- {thorvg_python-1.0.0 → thorvg_python-1.0.1}/conanfile.py +0 -0
- {thorvg_python-1.0.0 → thorvg_python-1.0.1}/setup.cfg +0 -0
- {thorvg_python-1.0.0 → thorvg_python-1.0.1}/src/thorvg_python/animation/__init__.py +0 -0
- {thorvg_python-1.0.0 → thorvg_python-1.0.1}/src/thorvg_python/base.py +0 -0
- {thorvg_python-1.0.0 → thorvg_python-1.0.1}/src/thorvg_python/canvas/__init__.py +0 -0
- {thorvg_python-1.0.0 → thorvg_python-1.0.1}/src/thorvg_python/canvas/sw.py +0 -0
- {thorvg_python-1.0.0 → thorvg_python-1.0.1}/src/thorvg_python/gradient/__init__.py +0 -0
- {thorvg_python-1.0.0 → thorvg_python-1.0.1}/src/thorvg_python/gradient/linear.py +0 -0
- {thorvg_python-1.0.0 → thorvg_python-1.0.1}/src/thorvg_python/gradient/radial.py +0 -0
- {thorvg_python-1.0.0 → thorvg_python-1.0.1}/src/thorvg_python/libthorvg.so +0 -0
- {thorvg_python-1.0.0 → thorvg_python-1.0.1}/src/thorvg_python/paint/__init__.py +0 -0
- {thorvg_python-1.0.0 → thorvg_python-1.0.1}/src/thorvg_python/paint/scene.py +0 -0
- {thorvg_python-1.0.0 → thorvg_python-1.0.1}/src/thorvg_python/paint/shape.py +0 -0
- {thorvg_python-1.0.0 → thorvg_python-1.0.1}/src/thorvg_python/py.typed +0 -0
- {thorvg_python-1.0.0 → thorvg_python-1.0.1}/src/thorvg_python.egg-info/SOURCES.txt +0 -0
- {thorvg_python-1.0.0 → thorvg_python-1.0.1}/src/thorvg_python.egg-info/dependency_links.txt +0 -0
- {thorvg_python-1.0.0 → thorvg_python-1.0.1}/src/thorvg_python.egg-info/not-zip-safe +0 -0
- {thorvg_python-1.0.0 → thorvg_python-1.0.1}/src/thorvg_python.egg-info/requires.txt +0 -0
- {thorvg_python-1.0.0 → thorvg_python-1.0.1}/src/thorvg_python.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: thorvg-python
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.1
|
|
4
4
|
Summary: A ctypes API for thorvg, a vector graphics engine supporting SVG and Lottie formats.
|
|
5
5
|
Author-email: chaudominic <chaudominic2@gmail.com>
|
|
6
6
|
License: GNU LESSER GENERAL PUBLIC LICENSE
|
|
@@ -514,6 +514,7 @@ Project-URL: Tracker, https://github.com/laggykiller/thorvg-python/issues
|
|
|
514
514
|
Keywords: thorvg,lottie,svg,ctypes,python
|
|
515
515
|
Classifier: Topic :: Multimedia :: Graphics
|
|
516
516
|
Requires-Python: >=3.7
|
|
517
|
+
Description-Content-Type: text/markdown
|
|
517
518
|
License-File: LICENSE
|
|
518
519
|
Provides-Extra: full
|
|
519
520
|
Requires-Dist: Pillow; extra == "full"
|
|
@@ -526,3 +527,121 @@ Requires-Dist: mypy; extra == "lint"
|
|
|
526
527
|
Requires-Dist: isort; extra == "lint"
|
|
527
528
|
Requires-Dist: types-Pillow; extra == "lint"
|
|
528
529
|
Dynamic: license-file
|
|
530
|
+
|
|
531
|
+
# thorvg-python
|
|
532
|
+
|
|
533
|
+
A ctypes API for thorvg, with additional functions for getting Pillow Image.
|
|
534
|
+
|
|
535
|
+
The functions mostly follow [thorvg/src/bindings/capi/thorvg_capi.h](https://github.com/thorvg/thorvg/blob/v0.15.16/src/bindings/capi/thorvg_capi.h)
|
|
536
|
+
|
|
537
|
+
Documentations: https://thorvg-python.readthedocs.io/en/latest/
|
|
538
|
+
|
|
539
|
+
## Table of contents
|
|
540
|
+
- [Installing](#installing)
|
|
541
|
+
- [Building from source](#building-from-source)
|
|
542
|
+
- [Examples](#examples)
|
|
543
|
+
- [Credits](#credits)
|
|
544
|
+
|
|
545
|
+
## Installing
|
|
546
|
+
|
|
547
|
+
Note that thorvg is included in the wheel package, you need not install libthorvg.
|
|
548
|
+
Version bundled is the version available on [Conan](https://conan.io/center/recipes/thorvg)
|
|
549
|
+
(Currently 0.15.16)
|
|
550
|
+
|
|
551
|
+
To install, run the following:
|
|
552
|
+
```bash
|
|
553
|
+
pip3 install thorvg-python
|
|
554
|
+
```
|
|
555
|
+
|
|
556
|
+
`Pillow` is optional dependency. It is required for `SwCanvas.get_pillow()`. To also install Pillow, run:
|
|
557
|
+
```bash
|
|
558
|
+
pip3 install thorvg-python[full]
|
|
559
|
+
```
|
|
560
|
+
|
|
561
|
+
## Examples
|
|
562
|
+
Drawing and getting pillow image
|
|
563
|
+
```python
|
|
564
|
+
import thorvg_python as tvg
|
|
565
|
+
|
|
566
|
+
engine = tvg.Engine(threads=4)
|
|
567
|
+
canvas = tvg.SwCanvas(engine)
|
|
568
|
+
canvas.set_target(512, 256) # w, h
|
|
569
|
+
|
|
570
|
+
rect = tvg.Shape(engine)
|
|
571
|
+
rect.append_rect(10, 10, 64, 64, 10, 10) # x, y, w, h, rx, ry
|
|
572
|
+
rect.set_fill_color(32, 64, 128, 100) # r, g, b, a
|
|
573
|
+
canvas.push(rect)
|
|
574
|
+
|
|
575
|
+
canvas.update()
|
|
576
|
+
canvas.draw()
|
|
577
|
+
canvas.sync()
|
|
578
|
+
|
|
579
|
+
im = canvas.get_pillow()
|
|
580
|
+
canvas.destroy()
|
|
581
|
+
engine.term()
|
|
582
|
+
```
|
|
583
|
+
|
|
584
|
+
Rendering lottie animation
|
|
585
|
+
```python
|
|
586
|
+
import thorvg_python as tvg
|
|
587
|
+
from PIL import Image
|
|
588
|
+
|
|
589
|
+
engine = tvg.Engine(threads=4)
|
|
590
|
+
canvas = tvg.SwCanvas(engine)
|
|
591
|
+
canvas.set_target(512, 512) # w, h
|
|
592
|
+
|
|
593
|
+
animation = tvg.LottieAnimation(engine)
|
|
594
|
+
picture = animation.get_picture()
|
|
595
|
+
picture.load("tests/test.json")
|
|
596
|
+
picture.set_size(512, 512)
|
|
597
|
+
|
|
598
|
+
canvas.push(picture)
|
|
599
|
+
|
|
600
|
+
ims: list[Image.Image] = []
|
|
601
|
+
result, total_frame = animation.get_total_frame()
|
|
602
|
+
result, duration = animation.get_duration()
|
|
603
|
+
frame_duration = duration / total_frame
|
|
604
|
+
# fps = total_frame / duration
|
|
605
|
+
for i in range(int(total_frame)):
|
|
606
|
+
animation.set_frame(i)
|
|
607
|
+
canvas.update()
|
|
608
|
+
canvas.draw()
|
|
609
|
+
canvas.sync()
|
|
610
|
+
im = canvas.get_pillow()
|
|
611
|
+
ims.append(im)
|
|
612
|
+
|
|
613
|
+
ims[0].save("test.apng", save_all=True, append_images=ims[1:], duration=frame_duration * 1000)
|
|
614
|
+
```
|
|
615
|
+
|
|
616
|
+
## Building from source
|
|
617
|
+
|
|
618
|
+
To build wheel, run the following:
|
|
619
|
+
```bash
|
|
620
|
+
git clone --recursive https://github.com/laggykiller/thorvg-python.git
|
|
621
|
+
cd thorvg-python
|
|
622
|
+
|
|
623
|
+
# To build wheel
|
|
624
|
+
python3 -m build .
|
|
625
|
+
|
|
626
|
+
# To install directly
|
|
627
|
+
pip3 install .
|
|
628
|
+
```
|
|
629
|
+
|
|
630
|
+
## Development
|
|
631
|
+
To run tests:
|
|
632
|
+
```bash
|
|
633
|
+
pip install pytest
|
|
634
|
+
pytest
|
|
635
|
+
```
|
|
636
|
+
|
|
637
|
+
To lint:
|
|
638
|
+
```bash
|
|
639
|
+
pip install ruff mypy isort
|
|
640
|
+
mypy
|
|
641
|
+
isort .
|
|
642
|
+
ruff check
|
|
643
|
+
ruff format
|
|
644
|
+
```
|
|
645
|
+
|
|
646
|
+
## Credits
|
|
647
|
+
- thorvg library: https://github.com/thorvg/thorvg
|
|
@@ -2,12 +2,13 @@
|
|
|
2
2
|
name = "thorvg-python"
|
|
3
3
|
description = "A ctypes API for thorvg, a vector graphics engine supporting SVG and Lottie formats."
|
|
4
4
|
requires-python = ">=3.7"
|
|
5
|
+
readme = "README.md"
|
|
5
6
|
license = { file = "LICENSE" }
|
|
6
7
|
authors = [{ "name" = "chaudominic", "email" = "chaudominic2@gmail.com" }]
|
|
7
8
|
keywords = ["thorvg", "lottie", "svg", "ctypes", "python"]
|
|
8
9
|
classifiers = ["Topic :: Multimedia :: Graphics"]
|
|
9
10
|
dependencies = []
|
|
10
|
-
version = "1.0.
|
|
11
|
+
version = "1.0.1"
|
|
11
12
|
|
|
12
13
|
[project.urls]
|
|
13
14
|
Repository = "https://github.com/laggykiller/thorvg-python"
|
|
@@ -34,8 +35,7 @@ lint = [
|
|
|
34
35
|
[build-system]
|
|
35
36
|
requires = [
|
|
36
37
|
"conan>=2.0",
|
|
37
|
-
"setuptools>=45"
|
|
38
|
-
"lipomerge>=0.1.1"
|
|
38
|
+
"setuptools>=45"
|
|
39
39
|
]
|
|
40
40
|
build-backend = "setuptools.build_meta"
|
|
41
41
|
|
|
@@ -178,12 +178,12 @@ def compile():
|
|
|
178
178
|
print(f"{lib_paths=}")
|
|
179
179
|
subprocess.run(
|
|
180
180
|
[
|
|
181
|
-
"
|
|
182
|
-
"-
|
|
183
|
-
"lipomerge",
|
|
181
|
+
"lipo",
|
|
182
|
+
"-create",
|
|
184
183
|
lib_paths[0],
|
|
185
184
|
lib_paths[1],
|
|
186
|
-
"
|
|
185
|
+
"-output",
|
|
186
|
+
"src/thorvg_python/libthorvg.dylib",
|
|
187
187
|
]
|
|
188
188
|
)
|
|
189
189
|
else:
|
|
@@ -55,9 +55,10 @@ class LottieAnimation(Animation):
|
|
|
55
55
|
Experimental API
|
|
56
56
|
"""
|
|
57
57
|
if slot is not None and slot != "":
|
|
58
|
-
|
|
58
|
+
slot_bytes = slot.encode() + b"\x00"
|
|
59
|
+
slot_arr_type = ctypes.c_char * len(slot_bytes)
|
|
59
60
|
slot_arr_type_ptr = ctypes.POINTER(slot_arr_type)
|
|
60
|
-
slot_arr_ptr = ctypes.pointer(slot_arr_type.from_buffer_copy(
|
|
61
|
+
slot_arr_ptr = ctypes.pointer(slot_arr_type.from_buffer_copy(slot_bytes))
|
|
61
62
|
else:
|
|
62
63
|
slot_arr_type_ptr = ctypes.c_void_p # type: ignore
|
|
63
64
|
slot_arr_ptr = ctypes.c_void_p() # type: ignore
|
|
@@ -88,8 +89,9 @@ class LottieAnimation(Animation):
|
|
|
88
89
|
.. note::
|
|
89
90
|
Experimental API
|
|
90
91
|
"""
|
|
91
|
-
|
|
92
|
-
|
|
92
|
+
marker_bytes = marker.encode() + b"\x00"
|
|
93
|
+
marker_arr_type = ctypes.c_char * len(marker_bytes)
|
|
94
|
+
marker_arr = marker_arr_type.from_buffer_copy(marker_bytes)
|
|
93
95
|
self.thorvg_lib.tvg_lottie_animation_set_marker.argtypes = [
|
|
94
96
|
ctypes.POINTER(AnimationStruct),
|
|
95
97
|
ctypes.POINTER(marker_arr_type),
|
|
@@ -245,8 +245,9 @@ class Engine:
|
|
|
245
245
|
|
|
246
246
|
.. versionadded:: 0.15
|
|
247
247
|
"""
|
|
248
|
-
|
|
249
|
-
|
|
248
|
+
path_bytes = path.encode() + b"\x00"
|
|
249
|
+
path_arr_type = ctypes.c_char * len(path_bytes)
|
|
250
|
+
path_arr = path_arr_type.from_buffer_copy(path_bytes)
|
|
250
251
|
self.thorvg_lib.tvg_font_load.argtypes = [
|
|
251
252
|
ctypes.POINTER(path_arr_type),
|
|
252
253
|
]
|
|
@@ -285,14 +286,17 @@ class Engine:
|
|
|
285
286
|
|
|
286
287
|
.. versionadded:: 0.15
|
|
287
288
|
"""
|
|
288
|
-
|
|
289
|
-
|
|
289
|
+
name_bytes = name.encode() + b"\x00"
|
|
290
|
+
name_bytes += b"\x00"
|
|
291
|
+
name_char_type = ctypes.c_char * len(name_bytes)
|
|
292
|
+
name_char = name_char_type.from_buffer_copy(name_bytes)
|
|
290
293
|
data_arr_type = ctypes.c_ubyte * len(data)
|
|
291
294
|
data_arr = data_arr_type.from_buffer_copy(data)
|
|
292
295
|
if mimetype is not None and mimetype != "":
|
|
293
|
-
|
|
296
|
+
mimetype_bytes = name.encode() + b"\x00"
|
|
297
|
+
mimetype_char_type = ctypes.c_char * len(mimetype_bytes)
|
|
294
298
|
mimetype_char_ptr_type = ctypes.POINTER(mimetype_char_type)
|
|
295
|
-
mimetype_char = mimetype_char_type.from_buffer_copy(
|
|
299
|
+
mimetype_char = mimetype_char_type.from_buffer_copy(mimetype_bytes)
|
|
296
300
|
mimetype_char_ptr = ctypes.pointer(mimetype_char)
|
|
297
301
|
else:
|
|
298
302
|
mimetype_char_ptr_type = ctypes.c_void_p # type: ignore
|
|
@@ -331,8 +335,9 @@ class Engine:
|
|
|
331
335
|
|
|
332
336
|
.. versionadded:: 0.15
|
|
333
337
|
"""
|
|
334
|
-
|
|
335
|
-
|
|
338
|
+
path_bytes = path.encode() + b"\x00"
|
|
339
|
+
path_arr_type = ctypes.c_char * len(path_bytes)
|
|
340
|
+
path_arr = path_arr_type.from_buffer_copy(path_bytes)
|
|
336
341
|
self.thorvg_lib.tvg_font_unload.argtypes = [
|
|
337
342
|
ctypes.POINTER(path_arr_type),
|
|
338
343
|
]
|
|
@@ -356,8 +361,9 @@ class Engine:
|
|
|
356
361
|
.. note::
|
|
357
362
|
Experimental API
|
|
358
363
|
"""
|
|
359
|
-
|
|
360
|
-
|
|
364
|
+
name_bytes = name.encode() + b"\x00"
|
|
365
|
+
name_char_type = ctypes.c_char * len(name_bytes)
|
|
366
|
+
name_char = name_char_type.from_buffer_copy(name_bytes)
|
|
361
367
|
self.thorvg_lib.tvg_accessor_generate_id.argtypes = [
|
|
362
368
|
ctypes.POINTER(name_char_type)
|
|
363
369
|
]
|
|
@@ -50,7 +50,8 @@ class Picture(Paint):
|
|
|
50
50
|
- NOT_SUPPORTED A file with an unknown extension.
|
|
51
51
|
:rtype: Result
|
|
52
52
|
"""
|
|
53
|
-
|
|
53
|
+
path_bytes = path.encode() + b"\x00"
|
|
54
|
+
path_char = ctypes.create_string_buffer(path_bytes)
|
|
54
55
|
self.thorvg_lib.tvg_picture_load.argtypes = [
|
|
55
56
|
ctypes.POINTER(PaintStruct),
|
|
56
57
|
ctypes.c_char * ctypes.sizeof(path_char),
|
|
@@ -124,10 +125,11 @@ class Picture(Paint):
|
|
|
124
125
|
.. warning::
|
|
125
126
|
: It's the user responsibility to release the ``data`` memory if the ``copy`` is ``true``.
|
|
126
127
|
"""
|
|
128
|
+
mimetype_bytes = mimetype.encode() + b"\x00"
|
|
127
129
|
data_arr_type = ctypes.c_char * len(data)
|
|
128
130
|
data_arr = data_arr_type.from_buffer_copy(data)
|
|
129
|
-
mimetype_char_type = ctypes.c_char * len(
|
|
130
|
-
mimetype_char = mimetype_char_type.from_buffer_copy(
|
|
131
|
+
mimetype_char_type = ctypes.c_char * len(mimetype_bytes)
|
|
132
|
+
mimetype_char = mimetype_char_type.from_buffer_copy(mimetype_bytes)
|
|
131
133
|
self.thorvg_lib.tvg_picture_load_data.argtypes = [
|
|
132
134
|
ctypes.POINTER(PaintStruct),
|
|
133
135
|
ctypes.POINTER(data_arr_type),
|
|
@@ -70,18 +70,20 @@ class Text(Paint):
|
|
|
70
70
|
text.set_font(None, 24, None)
|
|
71
71
|
"""
|
|
72
72
|
if name is not None and name != "":
|
|
73
|
-
|
|
73
|
+
name_bytes = name.encode() + b"\x00"
|
|
74
|
+
name_arr_type = ctypes.c_char * len(name_bytes)
|
|
74
75
|
name_arr_type_ptr = ctypes.POINTER(name_arr_type)
|
|
75
|
-
name_arr = name_arr_type.from_buffer_copy(
|
|
76
|
+
name_arr = name_arr_type.from_buffer_copy(name_bytes)
|
|
76
77
|
name_arr_ptr = ctypes.pointer(name_arr)
|
|
77
78
|
else:
|
|
78
79
|
name_arr_type_ptr = ctypes.c_void_p # type: ignore
|
|
79
80
|
name_arr_ptr = ctypes.c_void_p() # type: ignore
|
|
80
81
|
|
|
81
82
|
if style is not None and style != "":
|
|
82
|
-
|
|
83
|
+
style_bytes = style.encode() + b"\x00"
|
|
84
|
+
style_arr_type = ctypes.c_char * len(style_bytes)
|
|
83
85
|
style_arr_type_ptr = ctypes.POINTER(style_arr_type)
|
|
84
|
-
style_arr = style_arr_type.from_buffer_copy(
|
|
86
|
+
style_arr = style_arr_type.from_buffer_copy(style_bytes)
|
|
85
87
|
style_arr_ptr = ctypes.pointer(style_arr)
|
|
86
88
|
else:
|
|
87
89
|
style_arr_type_ptr = ctypes.c_void_p # type: ignore
|
|
@@ -118,8 +120,9 @@ class Text(Paint):
|
|
|
118
120
|
.. note::
|
|
119
121
|
Experimental API
|
|
120
122
|
"""
|
|
121
|
-
|
|
122
|
-
|
|
123
|
+
text_bytes = text.encode() + b"\x00"
|
|
124
|
+
text_arr_type = ctypes.c_char * len(text_bytes)
|
|
125
|
+
text_arr = text_arr_type.from_buffer_copy(text_bytes)
|
|
123
126
|
self.thorvg_lib.tvg_text_set_text.argtypes = [
|
|
124
127
|
ctypes.POINTER(PaintStruct),
|
|
125
128
|
ctypes.POINTER(text_arr_type),
|
|
@@ -62,8 +62,9 @@ class Saver:
|
|
|
62
62
|
Saving can be asynchronous if the assigned thread number is greater than zero. To guarantee the saving is done, call Saver.sync() afterwards.
|
|
63
63
|
.. seealso:: Saver.sync()
|
|
64
64
|
"""
|
|
65
|
+
path_bytes = path.encode() + b"\x00"
|
|
65
66
|
path_arr_type = ctypes.c_char * len(path)
|
|
66
|
-
path_arr = path_arr_type.from_buffer_copy(
|
|
67
|
+
path_arr = path_arr_type.from_buffer_copy(path_bytes)
|
|
67
68
|
self.thorvg_lib.tvg_saver_save.argtypes = [
|
|
68
69
|
ctypes.POINTER(SaverStruct),
|
|
69
70
|
ctypes.POINTER(PaintStruct),
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: thorvg-python
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.1
|
|
4
4
|
Summary: A ctypes API for thorvg, a vector graphics engine supporting SVG and Lottie formats.
|
|
5
5
|
Author-email: chaudominic <chaudominic2@gmail.com>
|
|
6
6
|
License: GNU LESSER GENERAL PUBLIC LICENSE
|
|
@@ -514,6 +514,7 @@ Project-URL: Tracker, https://github.com/laggykiller/thorvg-python/issues
|
|
|
514
514
|
Keywords: thorvg,lottie,svg,ctypes,python
|
|
515
515
|
Classifier: Topic :: Multimedia :: Graphics
|
|
516
516
|
Requires-Python: >=3.7
|
|
517
|
+
Description-Content-Type: text/markdown
|
|
517
518
|
License-File: LICENSE
|
|
518
519
|
Provides-Extra: full
|
|
519
520
|
Requires-Dist: Pillow; extra == "full"
|
|
@@ -526,3 +527,121 @@ Requires-Dist: mypy; extra == "lint"
|
|
|
526
527
|
Requires-Dist: isort; extra == "lint"
|
|
527
528
|
Requires-Dist: types-Pillow; extra == "lint"
|
|
528
529
|
Dynamic: license-file
|
|
530
|
+
|
|
531
|
+
# thorvg-python
|
|
532
|
+
|
|
533
|
+
A ctypes API for thorvg, with additional functions for getting Pillow Image.
|
|
534
|
+
|
|
535
|
+
The functions mostly follow [thorvg/src/bindings/capi/thorvg_capi.h](https://github.com/thorvg/thorvg/blob/v0.15.16/src/bindings/capi/thorvg_capi.h)
|
|
536
|
+
|
|
537
|
+
Documentations: https://thorvg-python.readthedocs.io/en/latest/
|
|
538
|
+
|
|
539
|
+
## Table of contents
|
|
540
|
+
- [Installing](#installing)
|
|
541
|
+
- [Building from source](#building-from-source)
|
|
542
|
+
- [Examples](#examples)
|
|
543
|
+
- [Credits](#credits)
|
|
544
|
+
|
|
545
|
+
## Installing
|
|
546
|
+
|
|
547
|
+
Note that thorvg is included in the wheel package, you need not install libthorvg.
|
|
548
|
+
Version bundled is the version available on [Conan](https://conan.io/center/recipes/thorvg)
|
|
549
|
+
(Currently 0.15.16)
|
|
550
|
+
|
|
551
|
+
To install, run the following:
|
|
552
|
+
```bash
|
|
553
|
+
pip3 install thorvg-python
|
|
554
|
+
```
|
|
555
|
+
|
|
556
|
+
`Pillow` is optional dependency. It is required for `SwCanvas.get_pillow()`. To also install Pillow, run:
|
|
557
|
+
```bash
|
|
558
|
+
pip3 install thorvg-python[full]
|
|
559
|
+
```
|
|
560
|
+
|
|
561
|
+
## Examples
|
|
562
|
+
Drawing and getting pillow image
|
|
563
|
+
```python
|
|
564
|
+
import thorvg_python as tvg
|
|
565
|
+
|
|
566
|
+
engine = tvg.Engine(threads=4)
|
|
567
|
+
canvas = tvg.SwCanvas(engine)
|
|
568
|
+
canvas.set_target(512, 256) # w, h
|
|
569
|
+
|
|
570
|
+
rect = tvg.Shape(engine)
|
|
571
|
+
rect.append_rect(10, 10, 64, 64, 10, 10) # x, y, w, h, rx, ry
|
|
572
|
+
rect.set_fill_color(32, 64, 128, 100) # r, g, b, a
|
|
573
|
+
canvas.push(rect)
|
|
574
|
+
|
|
575
|
+
canvas.update()
|
|
576
|
+
canvas.draw()
|
|
577
|
+
canvas.sync()
|
|
578
|
+
|
|
579
|
+
im = canvas.get_pillow()
|
|
580
|
+
canvas.destroy()
|
|
581
|
+
engine.term()
|
|
582
|
+
```
|
|
583
|
+
|
|
584
|
+
Rendering lottie animation
|
|
585
|
+
```python
|
|
586
|
+
import thorvg_python as tvg
|
|
587
|
+
from PIL import Image
|
|
588
|
+
|
|
589
|
+
engine = tvg.Engine(threads=4)
|
|
590
|
+
canvas = tvg.SwCanvas(engine)
|
|
591
|
+
canvas.set_target(512, 512) # w, h
|
|
592
|
+
|
|
593
|
+
animation = tvg.LottieAnimation(engine)
|
|
594
|
+
picture = animation.get_picture()
|
|
595
|
+
picture.load("tests/test.json")
|
|
596
|
+
picture.set_size(512, 512)
|
|
597
|
+
|
|
598
|
+
canvas.push(picture)
|
|
599
|
+
|
|
600
|
+
ims: list[Image.Image] = []
|
|
601
|
+
result, total_frame = animation.get_total_frame()
|
|
602
|
+
result, duration = animation.get_duration()
|
|
603
|
+
frame_duration = duration / total_frame
|
|
604
|
+
# fps = total_frame / duration
|
|
605
|
+
for i in range(int(total_frame)):
|
|
606
|
+
animation.set_frame(i)
|
|
607
|
+
canvas.update()
|
|
608
|
+
canvas.draw()
|
|
609
|
+
canvas.sync()
|
|
610
|
+
im = canvas.get_pillow()
|
|
611
|
+
ims.append(im)
|
|
612
|
+
|
|
613
|
+
ims[0].save("test.apng", save_all=True, append_images=ims[1:], duration=frame_duration * 1000)
|
|
614
|
+
```
|
|
615
|
+
|
|
616
|
+
## Building from source
|
|
617
|
+
|
|
618
|
+
To build wheel, run the following:
|
|
619
|
+
```bash
|
|
620
|
+
git clone --recursive https://github.com/laggykiller/thorvg-python.git
|
|
621
|
+
cd thorvg-python
|
|
622
|
+
|
|
623
|
+
# To build wheel
|
|
624
|
+
python3 -m build .
|
|
625
|
+
|
|
626
|
+
# To install directly
|
|
627
|
+
pip3 install .
|
|
628
|
+
```
|
|
629
|
+
|
|
630
|
+
## Development
|
|
631
|
+
To run tests:
|
|
632
|
+
```bash
|
|
633
|
+
pip install pytest
|
|
634
|
+
pytest
|
|
635
|
+
```
|
|
636
|
+
|
|
637
|
+
To lint:
|
|
638
|
+
```bash
|
|
639
|
+
pip install ruff mypy isort
|
|
640
|
+
mypy
|
|
641
|
+
isort .
|
|
642
|
+
ruff check
|
|
643
|
+
ruff format
|
|
644
|
+
```
|
|
645
|
+
|
|
646
|
+
## Credits
|
|
647
|
+
- thorvg library: https://github.com/thorvg/thorvg
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
2
|
import os
|
|
3
|
+
import platform
|
|
3
4
|
from importlib.util import find_spec
|
|
4
5
|
from typing import TYPE_CHECKING, List, Tuple
|
|
5
6
|
|
|
@@ -10,6 +11,11 @@ import thorvg_python as tvg
|
|
|
10
11
|
PILLOW_LOADED = True if find_spec("PIL") else False
|
|
11
12
|
file_dir = os.path.split(__file__)[0]
|
|
12
13
|
|
|
14
|
+
if platform.system() == "Windows":
|
|
15
|
+
ref_dir = os.path.join(file_dir, "ref_win")
|
|
16
|
+
else:
|
|
17
|
+
ref_dir = os.path.join(file_dir, "ref")
|
|
18
|
+
|
|
13
19
|
if TYPE_CHECKING:
|
|
14
20
|
from PIL import Image
|
|
15
21
|
|
|
@@ -17,7 +23,7 @@ if TYPE_CHECKING:
|
|
|
17
23
|
def check_im_same(im: "Image.Image", im_ref_name: str):
|
|
18
24
|
from PIL import Image, ImageChops
|
|
19
25
|
|
|
20
|
-
im_ref = Image.open(os.path.join(
|
|
26
|
+
im_ref = Image.open(os.path.join(ref_dir, im_ref_name))
|
|
21
27
|
return ImageChops.difference(im_ref, im).getbbox() is None
|
|
22
28
|
|
|
23
29
|
|
|
@@ -653,6 +659,9 @@ def test_picture_load_raw_copy_true():
|
|
|
653
659
|
|
|
654
660
|
|
|
655
661
|
@pytest.mark.skipif(PILLOW_LOADED is False, reason="Pillow not installed")
|
|
662
|
+
@pytest.mark.skipif(
|
|
663
|
+
platform.system() == "Windows", reason="Known failure if on Windows"
|
|
664
|
+
)
|
|
656
665
|
def test_picture_load_raw_copy_false():
|
|
657
666
|
_test_picture_load_raw("test.png", "test_picture_png_ref.png", False)
|
|
658
667
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|