dynimg 0.1.14__tar.gz → 0.1.15__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.
- {dynimg-0.1.14 → dynimg-0.1.15}/.claude/settings.local.json +3 -1
- dynimg-0.1.15/CLAUDE.md +4 -0
- {dynimg-0.1.14 → dynimg-0.1.15}/Cargo.lock +200 -2
- {dynimg-0.1.14 → dynimg-0.1.15}/Cargo.toml +2 -2
- {dynimg-0.1.14 → dynimg-0.1.15}/Makefile +1 -1
- {dynimg-0.1.14 → dynimg-0.1.15}/PKG-INFO +128 -30
- {dynimg-0.1.14 → dynimg-0.1.15}/README.md +127 -29
- dynimg-0.1.15/examples/transparent.html +39 -0
- {dynimg-0.1.14 → dynimg-0.1.15}/pyproject.toml +1 -1
- {dynimg-0.1.14 → dynimg-0.1.15}/python/dynimg/__init__.pyi +14 -1
- {dynimg-0.1.14 → dynimg-0.1.15}/scripts/snapshot-tests.sh +6 -0
- {dynimg-0.1.14 → dynimg-0.1.15}/src/lib.rs +70 -13
- {dynimg-0.1.14 → dynimg-0.1.15}/src/main.rs +7 -0
- {dynimg-0.1.14 → dynimg-0.1.15}/src/python.rs +13 -6
- {dynimg-0.1.14 → dynimg-0.1.15}/test_wheels/.gitignore +2 -0
- {dynimg-0.1.14 → dynimg-0.1.15}/test_wheels/test_dynimg.py +33 -27
- dynimg-0.1.15/tests/snapshots/inline-only-jpg.jpg +0 -0
- dynimg-0.1.15/tests/snapshots/transparent-jpg.jpg +0 -0
- dynimg-0.1.15/tests/snapshots/transparent-webp.webp +0 -0
- dynimg-0.1.15/tests/snapshots/transparent.png +0 -0
- dynimg-0.1.14/CLAUDE.md +0 -2
- dynimg-0.1.14/tests/snapshots/inline-only-jpg.jpg +0 -0
- {dynimg-0.1.14 → dynimg-0.1.15}/.github/workflows/build-wheels.yml +0 -0
- {dynimg-0.1.14 → dynimg-0.1.15}/.github/workflows/ci.yml +0 -0
- {dynimg-0.1.14 → dynimg-0.1.15}/.github/workflows/release.yml +0 -0
- {dynimg-0.1.14 → dynimg-0.1.15}/.gitignore +0 -0
- {dynimg-0.1.14 → dynimg-0.1.15}/.pearls/CLAUDE.md +0 -0
- {dynimg-0.1.14 → dynimg-0.1.15}/.pearls/issues.jsonl +0 -0
- {dynimg-0.1.14 → dynimg-0.1.15}/LICENSE +0 -0
- {dynimg-0.1.14 → dynimg-0.1.15}/codebook.toml +0 -0
- {dynimg-0.1.14 → dynimg-0.1.15}/examples/assets/PlaywriteINGuides-Regular.ttf +0 -0
- {dynimg-0.1.14 → dynimg-0.1.15}/examples/assets/RobotoMono-Bold.ttf +0 -0
- {dynimg-0.1.14 → dynimg-0.1.15}/examples/assets/RobotoMono-Bold.woff2 +0 -0
- {dynimg-0.1.14 → dynimg-0.1.15}/examples/assets/logo.svg +0 -0
- {dynimg-0.1.14 → dynimg-0.1.15}/examples/assets/servo.css +0 -0
- {dynimg-0.1.14 → dynimg-0.1.15}/examples/assets/style.css +0 -0
- {dynimg-0.1.14 → dynimg-0.1.15}/examples/google-fonts.html +0 -0
- {dynimg-0.1.14 → dynimg-0.1.15}/examples/inline-only.html +0 -0
- {dynimg-0.1.14 → dynimg-0.1.15}/examples/local-assets.html +0 -0
- {dynimg-0.1.14 → dynimg-0.1.15}/examples/local-font-woff2.html +0 -0
- {dynimg-0.1.14 → dynimg-0.1.15}/examples/local-font.html +0 -0
- {dynimg-0.1.14 → dynimg-0.1.15}/examples/mixed-assets.html +0 -0
- {dynimg-0.1.14 → dynimg-0.1.15}/examples/og-image.html +0 -0
- {dynimg-0.1.14 → dynimg-0.1.15}/examples/quote.html +0 -0
- {dynimg-0.1.14 → dynimg-0.1.15}/examples/remote-image.html +0 -0
- {dynimg-0.1.14 → dynimg-0.1.15}/examples/servo.html +0 -0
- {dynimg-0.1.14 → dynimg-0.1.15}/examples/social-card.html +0 -0
- {dynimg-0.1.14 → dynimg-0.1.15}/python/dynimg/__init__.py +0 -0
- {dynimg-0.1.14 → dynimg-0.1.15}/python/dynimg/py.typed +0 -0
- {dynimg-0.1.14 → dynimg-0.1.15}/scripts/release.sh +0 -0
- {dynimg-0.1.14 → dynimg-0.1.15}/scripts/render-examples.sh +0 -0
- {dynimg-0.1.14 → dynimg-0.1.15}/test_wheels/README.md +0 -0
- {dynimg-0.1.14 → dynimg-0.1.15}/test_wheels/debug_parser.py +0 -0
- {dynimg-0.1.14 → dynimg-0.1.15}/test_wheels/debug_verbose.py +0 -0
- {dynimg-0.1.14 → dynimg-0.1.15}/test_wheels/test_from_ci.sh +0 -0
- {dynimg-0.1.14 → dynimg-0.1.15}/tests/snapshots/inline-custom-size.png +0 -0
- {dynimg-0.1.14 → dynimg-0.1.15}/tests/snapshots/inline-only-webp.webp +0 -0
- {dynimg-0.1.14 → dynimg-0.1.15}/tests/snapshots/inline-only.png +0 -0
- {dynimg-0.1.14 → dynimg-0.1.15}/tests/snapshots/og-image.png +0 -0
- {dynimg-0.1.14 → dynimg-0.1.15}/tests/snapshots/quote.png +0 -0
- {dynimg-0.1.14 → dynimg-0.1.15}/tests/snapshots/social-card.png +0 -0
dynimg-0.1.15/CLAUDE.md
ADDED
|
@@ -26,6 +26,15 @@ dependencies = [
|
|
|
26
26
|
"memchr",
|
|
27
27
|
]
|
|
28
28
|
|
|
29
|
+
[[package]]
|
|
30
|
+
name = "aligned-vec"
|
|
31
|
+
version = "0.6.4"
|
|
32
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
33
|
+
checksum = "dc890384c8602f339876ded803c97ad529f3842aba97f6392b3dba0dd171769b"
|
|
34
|
+
dependencies = [
|
|
35
|
+
"equator",
|
|
36
|
+
]
|
|
37
|
+
|
|
29
38
|
[[package]]
|
|
30
39
|
name = "alloc-no-stdlib"
|
|
31
40
|
version = "2.0.4"
|
|
@@ -151,6 +160,27 @@ dependencies = [
|
|
|
151
160
|
"serde",
|
|
152
161
|
]
|
|
153
162
|
|
|
163
|
+
[[package]]
|
|
164
|
+
name = "archmage"
|
|
165
|
+
version = "0.3.0"
|
|
166
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
167
|
+
checksum = "e5778a98b0714014089227472fd4342aacbd581d58ab673cbba6f6bf9fb5b5cd"
|
|
168
|
+
dependencies = [
|
|
169
|
+
"archmage-macros",
|
|
170
|
+
"bytemuck",
|
|
171
|
+
]
|
|
172
|
+
|
|
173
|
+
[[package]]
|
|
174
|
+
name = "archmage-macros"
|
|
175
|
+
version = "0.3.0"
|
|
176
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
177
|
+
checksum = "80979662181a630a1e7a4f9f25174e990f44fc0c4e534e11c563fee10c9b8a1e"
|
|
178
|
+
dependencies = [
|
|
179
|
+
"proc-macro2",
|
|
180
|
+
"quote",
|
|
181
|
+
"syn",
|
|
182
|
+
]
|
|
183
|
+
|
|
154
184
|
[[package]]
|
|
155
185
|
name = "arrayref"
|
|
156
186
|
version = "0.3.9"
|
|
@@ -754,7 +784,7 @@ dependencies = [
|
|
|
754
784
|
|
|
755
785
|
[[package]]
|
|
756
786
|
name = "dynimg"
|
|
757
|
-
version = "0.1.
|
|
787
|
+
version = "0.1.15"
|
|
758
788
|
dependencies = [
|
|
759
789
|
"anyhow",
|
|
760
790
|
"anyrender",
|
|
@@ -766,7 +796,6 @@ dependencies = [
|
|
|
766
796
|
"blitz-traits",
|
|
767
797
|
"bytes",
|
|
768
798
|
"clap",
|
|
769
|
-
"image",
|
|
770
799
|
"kurbo",
|
|
771
800
|
"libc",
|
|
772
801
|
"peniko",
|
|
@@ -776,6 +805,7 @@ dependencies = [
|
|
|
776
805
|
"tokio",
|
|
777
806
|
"tracing-subscriber",
|
|
778
807
|
"webp",
|
|
808
|
+
"zenjpeg",
|
|
779
809
|
]
|
|
780
810
|
|
|
781
811
|
[[package]]
|
|
@@ -793,6 +823,32 @@ dependencies = [
|
|
|
793
823
|
"cfg-if",
|
|
794
824
|
]
|
|
795
825
|
|
|
826
|
+
[[package]]
|
|
827
|
+
name = "enough"
|
|
828
|
+
version = "0.3.1"
|
|
829
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
830
|
+
checksum = "65641ff0923e45cf34a4cb0115080cb7fc8bf4fd419c2207670d5722bab4c581"
|
|
831
|
+
|
|
832
|
+
[[package]]
|
|
833
|
+
name = "equator"
|
|
834
|
+
version = "0.4.2"
|
|
835
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
836
|
+
checksum = "4711b213838dfee0117e3be6ac926007d7f433d7bbe33595975d4190cb07e6fc"
|
|
837
|
+
dependencies = [
|
|
838
|
+
"equator-macro",
|
|
839
|
+
]
|
|
840
|
+
|
|
841
|
+
[[package]]
|
|
842
|
+
name = "equator-macro"
|
|
843
|
+
version = "0.4.2"
|
|
844
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
845
|
+
checksum = "44f23cf4b44bfce11a86ace86f8a73ffdec849c9fd00a386a53d278bd9e81fb3"
|
|
846
|
+
dependencies = [
|
|
847
|
+
"proc-macro2",
|
|
848
|
+
"quote",
|
|
849
|
+
"syn",
|
|
850
|
+
]
|
|
851
|
+
|
|
796
852
|
[[package]]
|
|
797
853
|
name = "equivalent"
|
|
798
854
|
version = "1.0.2"
|
|
@@ -1522,6 +1578,12 @@ version = "0.14.0"
|
|
|
1522
1578
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1523
1579
|
checksum = "09e54e57b4c48b40f7aec75635392b12b3421fa26fe8b4332e63138ed278459c"
|
|
1524
1580
|
|
|
1581
|
+
[[package]]
|
|
1582
|
+
name = "imgref"
|
|
1583
|
+
version = "1.12.0"
|
|
1584
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1585
|
+
checksum = "e7c5cedc30da3a610cac6b4ba17597bdf7152cf974e8aab3afb3d54455e371c8"
|
|
1586
|
+
|
|
1525
1587
|
[[package]]
|
|
1526
1588
|
name = "indexmap"
|
|
1527
1589
|
version = "2.13.0"
|
|
@@ -1659,6 +1721,19 @@ dependencies = [
|
|
|
1659
1721
|
"glob",
|
|
1660
1722
|
]
|
|
1661
1723
|
|
|
1724
|
+
[[package]]
|
|
1725
|
+
name = "linear-srgb"
|
|
1726
|
+
version = "0.3.2"
|
|
1727
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1728
|
+
checksum = "153732436b90b689934ad2d2997d5f0d2416163017ac76e6c0475dce9e7999c3"
|
|
1729
|
+
dependencies = [
|
|
1730
|
+
"bytemuck",
|
|
1731
|
+
"multiversed",
|
|
1732
|
+
"multiversion",
|
|
1733
|
+
"num-traits",
|
|
1734
|
+
"wide",
|
|
1735
|
+
]
|
|
1736
|
+
|
|
1662
1737
|
[[package]]
|
|
1663
1738
|
name = "linebender_resource_handle"
|
|
1664
1739
|
version = "0.1.1"
|
|
@@ -1698,6 +1773,16 @@ version = "0.1.2"
|
|
|
1698
1773
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1699
1774
|
checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154"
|
|
1700
1775
|
|
|
1776
|
+
[[package]]
|
|
1777
|
+
name = "magetypes"
|
|
1778
|
+
version = "0.3.0"
|
|
1779
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1780
|
+
checksum = "79bcaaebc5420c1dfb6a2db979cf86c7f852fea4013de3920d0f0395ac9ea5a7"
|
|
1781
|
+
dependencies = [
|
|
1782
|
+
"archmage",
|
|
1783
|
+
"bytemuck",
|
|
1784
|
+
]
|
|
1785
|
+
|
|
1701
1786
|
[[package]]
|
|
1702
1787
|
name = "malloc_size_of_derive"
|
|
1703
1788
|
version = "0.1.3"
|
|
@@ -1803,6 +1888,39 @@ dependencies = [
|
|
|
1803
1888
|
"windows-sys 0.61.2",
|
|
1804
1889
|
]
|
|
1805
1890
|
|
|
1891
|
+
[[package]]
|
|
1892
|
+
name = "multiversed"
|
|
1893
|
+
version = "0.1.0"
|
|
1894
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1895
|
+
checksum = "31eede710ee60ecb1708685a9d948d25a67ee3940ee8a1096431590cb21eef7d"
|
|
1896
|
+
dependencies = [
|
|
1897
|
+
"proc-macro2",
|
|
1898
|
+
"quote",
|
|
1899
|
+
"syn",
|
|
1900
|
+
]
|
|
1901
|
+
|
|
1902
|
+
[[package]]
|
|
1903
|
+
name = "multiversion"
|
|
1904
|
+
version = "0.8.0"
|
|
1905
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1906
|
+
checksum = "7edb7f0ff51249dfda9ab96b5823695e15a052dc15074c9dbf3d118afaf2c201"
|
|
1907
|
+
dependencies = [
|
|
1908
|
+
"multiversion-macros",
|
|
1909
|
+
"target-features",
|
|
1910
|
+
]
|
|
1911
|
+
|
|
1912
|
+
[[package]]
|
|
1913
|
+
name = "multiversion-macros"
|
|
1914
|
+
version = "0.8.0"
|
|
1915
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1916
|
+
checksum = "b093064383341eb3271f42e381cb8f10a01459478446953953c75d24bd339fc0"
|
|
1917
|
+
dependencies = [
|
|
1918
|
+
"proc-macro2",
|
|
1919
|
+
"quote",
|
|
1920
|
+
"syn",
|
|
1921
|
+
"target-features",
|
|
1922
|
+
]
|
|
1923
|
+
|
|
1806
1924
|
[[package]]
|
|
1807
1925
|
name = "new_debug_unreachable"
|
|
1808
1926
|
version = "1.0.6"
|
|
@@ -1851,6 +1969,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
|
1851
1969
|
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
|
|
1852
1970
|
dependencies = [
|
|
1853
1971
|
"autocfg",
|
|
1972
|
+
"libm",
|
|
1854
1973
|
]
|
|
1855
1974
|
|
|
1856
1975
|
[[package]]
|
|
@@ -2444,6 +2563,15 @@ dependencies = [
|
|
|
2444
2563
|
"tower-service",
|
|
2445
2564
|
]
|
|
2446
2565
|
|
|
2566
|
+
[[package]]
|
|
2567
|
+
name = "rgb"
|
|
2568
|
+
version = "0.8.52"
|
|
2569
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
2570
|
+
checksum = "0c6a884d2998352bb4daf0183589aec883f16a6da1f4dde84d8e2e9a5409a1ce"
|
|
2571
|
+
dependencies = [
|
|
2572
|
+
"bytemuck",
|
|
2573
|
+
]
|
|
2574
|
+
|
|
2447
2575
|
[[package]]
|
|
2448
2576
|
name = "ring"
|
|
2449
2577
|
version = "0.17.14"
|
|
@@ -2566,6 +2694,21 @@ version = "1.0.22"
|
|
|
2566
2694
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
2567
2695
|
checksum = "a50f4cf475b65d88e057964e0e9bb1f0aa9bbb2036dc65c64596b42932536984"
|
|
2568
2696
|
|
|
2697
|
+
[[package]]
|
|
2698
|
+
name = "safe_arch"
|
|
2699
|
+
version = "1.0.0"
|
|
2700
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
2701
|
+
checksum = "1f7caad094bd561859bcd467734a720c3c1f5d1f338995351fefe2190c45efed"
|
|
2702
|
+
dependencies = [
|
|
2703
|
+
"bytemuck",
|
|
2704
|
+
]
|
|
2705
|
+
|
|
2706
|
+
[[package]]
|
|
2707
|
+
name = "safe_unaligned_simd"
|
|
2708
|
+
version = "0.2.4"
|
|
2709
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
2710
|
+
checksum = "c1d612ce01a584cfab72164fb3f689112249fafeab7b4181c14601d19b34cb0a"
|
|
2711
|
+
|
|
2569
2712
|
[[package]]
|
|
2570
2713
|
name = "same-file"
|
|
2571
2714
|
version = "1.0.6"
|
|
@@ -3098,6 +3241,12 @@ dependencies = [
|
|
|
3098
3241
|
"slotmap",
|
|
3099
3242
|
]
|
|
3100
3243
|
|
|
3244
|
+
[[package]]
|
|
3245
|
+
name = "target-features"
|
|
3246
|
+
version = "0.1.6"
|
|
3247
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
3248
|
+
checksum = "c1bbb9f3c5c463a01705937a24fdabc5047929ac764b2d5b9cf681c1f5041ed5"
|
|
3249
|
+
|
|
3101
3250
|
[[package]]
|
|
3102
3251
|
name = "target-lexicon"
|
|
3103
3252
|
version = "0.13.4"
|
|
@@ -3784,6 +3933,22 @@ version = "0.1.12"
|
|
|
3784
3933
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
3785
3934
|
checksum = "a28ac98ddc8b9274cb41bb4d9d4d5c425b6020c50c46f25559911905610b4a88"
|
|
3786
3935
|
|
|
3936
|
+
[[package]]
|
|
3937
|
+
name = "whereat"
|
|
3938
|
+
version = "0.1.3"
|
|
3939
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
3940
|
+
checksum = "3ec598a1ade4224cfe3c5dace0d5d7deec9ed670503ff99d4946973c8c094534"
|
|
3941
|
+
|
|
3942
|
+
[[package]]
|
|
3943
|
+
name = "wide"
|
|
3944
|
+
version = "1.1.1"
|
|
3945
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
3946
|
+
checksum = "ac11b009ebeae802ed758530b6496784ebfee7a87b9abfbcaf3bbe25b814eb25"
|
|
3947
|
+
dependencies = [
|
|
3948
|
+
"bytemuck",
|
|
3949
|
+
"safe_arch",
|
|
3950
|
+
]
|
|
3951
|
+
|
|
3787
3952
|
[[package]]
|
|
3788
3953
|
name = "winapi-util"
|
|
3789
3954
|
version = "0.1.11"
|
|
@@ -4210,6 +4375,39 @@ dependencies = [
|
|
|
4210
4375
|
"synstructure",
|
|
4211
4376
|
]
|
|
4212
4377
|
|
|
4378
|
+
[[package]]
|
|
4379
|
+
name = "yuv"
|
|
4380
|
+
version = "0.8.10"
|
|
4381
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
4382
|
+
checksum = "447d8234fba933a5198401c673607dd75758bab32136766da61711cc362294e9"
|
|
4383
|
+
dependencies = [
|
|
4384
|
+
"num-traits",
|
|
4385
|
+
]
|
|
4386
|
+
|
|
4387
|
+
[[package]]
|
|
4388
|
+
name = "zenjpeg"
|
|
4389
|
+
version = "0.4.0"
|
|
4390
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
4391
|
+
checksum = "7bbccbe8dcf2cc21579981070905b6120ec82a45aa92b1715d28e05941390c50"
|
|
4392
|
+
dependencies = [
|
|
4393
|
+
"aligned-vec",
|
|
4394
|
+
"archmage",
|
|
4395
|
+
"bytemuck",
|
|
4396
|
+
"enough",
|
|
4397
|
+
"imgref",
|
|
4398
|
+
"linear-srgb",
|
|
4399
|
+
"magetypes",
|
|
4400
|
+
"multiversed",
|
|
4401
|
+
"multiversion",
|
|
4402
|
+
"rgb",
|
|
4403
|
+
"safe_unaligned_simd",
|
|
4404
|
+
"thiserror 2.0.18",
|
|
4405
|
+
"tinyvec",
|
|
4406
|
+
"whereat",
|
|
4407
|
+
"wide",
|
|
4408
|
+
"yuv",
|
|
4409
|
+
]
|
|
4410
|
+
|
|
4213
4411
|
[[package]]
|
|
4214
4412
|
name = "zeno"
|
|
4215
4413
|
version = "0.3.3"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[package]
|
|
2
2
|
name = "dynimg"
|
|
3
|
-
version = "0.1.
|
|
3
|
+
version = "0.1.15"
|
|
4
4
|
edition = "2024"
|
|
5
5
|
description = "A fast library and CLI for rendering HTML/CSS to images"
|
|
6
6
|
license = "MIT"
|
|
@@ -48,7 +48,7 @@ clap = { version = "4", features = ["derive"] }
|
|
|
48
48
|
|
|
49
49
|
# Image encoding
|
|
50
50
|
png = "0.18"
|
|
51
|
-
|
|
51
|
+
zenjpeg = "0.4"
|
|
52
52
|
webp = "0.3"
|
|
53
53
|
|
|
54
54
|
# Async runtime (needed for blitz-net)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dynimg
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.15
|
|
4
4
|
Classifier: Development Status :: 4 - Beta
|
|
5
5
|
Classifier: Intended Audience :: Developers
|
|
6
6
|
Classifier: License :: OSI Approved :: MIT License
|
|
@@ -28,10 +28,20 @@ A fast library and CLI for rendering HTML/CSS to images. Use from Python, Rust,
|
|
|
28
28
|
|
|
29
29
|
Perfect for generating dynamic images like Open Graph (OG) images, social media cards, email headers, and more.
|
|
30
30
|
|
|
31
|
+
## Example Output
|
|
32
|
+
|
|
33
|
+
<table>
|
|
34
|
+
<tr>
|
|
35
|
+
<td><img src="tests/snapshots/og-image.png" width="400" alt="OG Image Example"></td>
|
|
36
|
+
<td><img src="tests/snapshots/social-card.png" width="400" alt="Social Card Example"></td>
|
|
37
|
+
</tr>
|
|
38
|
+
</table>
|
|
39
|
+
|
|
31
40
|
## Features
|
|
32
41
|
|
|
33
42
|
- **Python + Rust + CLI**: Use from Python, as a Rust library, or command-line tool
|
|
34
43
|
- **Multiple output formats**: PNG, WebP (lossless), and JPEG
|
|
44
|
+
- **Transparent backgrounds**: PNG and WebP support transparency (JPEG uses white)
|
|
35
45
|
- **High-quality rendering**: Configurable scale factor for retina displays
|
|
36
46
|
- **Fast**: Native Rust performance with no browser overhead
|
|
37
47
|
- **Secure by default**: Network and filesystem access disabled unless explicitly enabled
|
|
@@ -103,7 +113,8 @@ let options = RenderOptions::default()
|
|
|
103
113
|
.height(630)
|
|
104
114
|
.scale(2.0)
|
|
105
115
|
.allow_net()
|
|
106
|
-
.assets_dir("./assets")
|
|
116
|
+
.assets_dir("./assets")
|
|
117
|
+
.background("#ffffff"); // CSS hex color (default: transparent)
|
|
107
118
|
|
|
108
119
|
// Or struct initialization
|
|
109
120
|
let options = RenderOptions {
|
|
@@ -113,6 +124,7 @@ let options = RenderOptions {
|
|
|
113
124
|
allow_net: true,
|
|
114
125
|
assets_dir: Some("./assets".into()),
|
|
115
126
|
base_url: None,
|
|
127
|
+
background: Some("#ffffff".into()), // None = transparent
|
|
116
128
|
};
|
|
117
129
|
```
|
|
118
130
|
|
|
@@ -138,16 +150,32 @@ dynimg input.html -o output.png
|
|
|
138
150
|
### Output Formats
|
|
139
151
|
|
|
140
152
|
```bash
|
|
141
|
-
# PNG (lossless)
|
|
153
|
+
# PNG (lossless, supports transparency)
|
|
142
154
|
dynimg input.html -o image.png
|
|
143
155
|
|
|
144
|
-
# WebP (lossless)
|
|
156
|
+
# WebP (lossless, supports transparency)
|
|
145
157
|
dynimg input.html -o image.webp
|
|
146
158
|
|
|
147
|
-
# JPEG (lossy)
|
|
159
|
+
# JPEG (lossy, no transparency - uses white background)
|
|
148
160
|
dynimg input.html -o image.jpg --quality 90
|
|
149
161
|
```
|
|
150
162
|
|
|
163
|
+
### Transparent Backgrounds
|
|
164
|
+
|
|
165
|
+
PNG and WebP output supports transparent backgrounds. Simply don't set a background on your HTML body:
|
|
166
|
+
|
|
167
|
+
```html
|
|
168
|
+
<body style="padding: 20px;">
|
|
169
|
+
<div style="background: white; border-radius: 8px; padding: 20px;">
|
|
170
|
+
Content with transparent surrounding area
|
|
171
|
+
</div>
|
|
172
|
+
</body>
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
<img src="tests/snapshots/transparent.png" width="300" alt="Transparent background example">
|
|
176
|
+
|
|
177
|
+
JPEG doesn't support transparency, so it automatically uses a white background.
|
|
178
|
+
|
|
151
179
|
### Image Dimensions
|
|
152
180
|
|
|
153
181
|
The `--width` and `--height` options set the **viewport size** (CSS layout dimensions). The actual output image is scaled by the `--scale` factor (default: 2x for high-DPI/retina displays).
|
|
@@ -279,6 +307,7 @@ options = dynimg.RenderOptions(
|
|
|
279
307
|
allow_net=True, # Allow network requests (default: False)
|
|
280
308
|
assets_dir="./assets", # Local assets directory (default: None)
|
|
281
309
|
base_url="https://example.com", # Base URL for relative URLs (default: None)
|
|
310
|
+
background="#ffffff", # CSS hex color (default: transparent)
|
|
282
311
|
)
|
|
283
312
|
|
|
284
313
|
image = dynimg.render(html, options)
|
|
@@ -318,7 +347,14 @@ You can configure rendering options directly in your HTML using meta tags. CLI f
|
|
|
318
347
|
|
|
319
348
|
This is useful for templates that should always render at specific dimensions. Remember: the output image size is viewport × scale.
|
|
320
349
|
|
|
321
|
-
## Example
|
|
350
|
+
## Example Templates
|
|
351
|
+
|
|
352
|
+
### OG Image
|
|
353
|
+
|
|
354
|
+
<img src="tests/snapshots/og-image.png" width="500" alt="OG Image Example">
|
|
355
|
+
|
|
356
|
+
<details>
|
|
357
|
+
<summary>View HTML</summary>
|
|
322
358
|
|
|
323
359
|
```html
|
|
324
360
|
<!DOCTYPE html>
|
|
@@ -327,40 +363,99 @@ This is useful for templates that should always render at specific dimensions. R
|
|
|
327
363
|
<meta name="dynimg:width" content="1200">
|
|
328
364
|
<meta name="dynimg:height" content="630">
|
|
329
365
|
<style>
|
|
330
|
-
* {
|
|
331
|
-
|
|
332
|
-
padding: 0;
|
|
333
|
-
box-sizing: border-box;
|
|
334
|
-
}
|
|
366
|
+
* { margin: 0; padding: 0; box-sizing: border-box; }
|
|
367
|
+
body { font-family: system-ui, -apple-system, sans-serif; }
|
|
335
368
|
.container {
|
|
336
369
|
width: 1200px;
|
|
337
370
|
height: 630px;
|
|
338
371
|
display: flex;
|
|
339
372
|
flex-direction: column;
|
|
340
373
|
justify-content: center;
|
|
341
|
-
|
|
374
|
+
padding: 80px;
|
|
342
375
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
343
|
-
font-family: system-ui, sans-serif;
|
|
344
376
|
}
|
|
345
|
-
h1 {
|
|
377
|
+
h1 { color: white; font-size: 72px; font-weight: 700; line-height: 1.1; margin-bottom: 24px; }
|
|
378
|
+
p { color: rgba(255, 255, 255, 0.85); font-size: 32px; }
|
|
379
|
+
.footer { position: absolute; bottom: 40px; left: 80px; color: rgba(255, 255, 255, 0.6); font-size: 24px; }
|
|
380
|
+
</style>
|
|
381
|
+
</head>
|
|
382
|
+
<body>
|
|
383
|
+
<div class="container">
|
|
384
|
+
<h1>Your Blog Post Title Here</h1>
|
|
385
|
+
<p>A compelling subtitle that captures attention</p>
|
|
386
|
+
<div class="footer">yoursite.com</div>
|
|
387
|
+
</div>
|
|
388
|
+
</body>
|
|
389
|
+
</html>
|
|
390
|
+
```
|
|
391
|
+
</details>
|
|
392
|
+
|
|
393
|
+
### Social Card
|
|
394
|
+
|
|
395
|
+
<img src="tests/snapshots/social-card.png" width="500" alt="Social Card Example">
|
|
396
|
+
|
|
397
|
+
<details>
|
|
398
|
+
<summary>View HTML</summary>
|
|
399
|
+
|
|
400
|
+
```html
|
|
401
|
+
<!DOCTYPE html>
|
|
402
|
+
<html>
|
|
403
|
+
<head>
|
|
404
|
+
<meta name="dynimg:width" content="1200">
|
|
405
|
+
<meta name="dynimg:height" content="675">
|
|
406
|
+
<style>
|
|
407
|
+
* { margin: 0; padding: 0; box-sizing: border-box; }
|
|
408
|
+
body { font-family: system-ui, -apple-system, sans-serif; }
|
|
409
|
+
.card {
|
|
410
|
+
width: 1200px;
|
|
411
|
+
height: 675px;
|
|
412
|
+
background: #0f172a;
|
|
413
|
+
display: flex;
|
|
414
|
+
padding: 60px;
|
|
415
|
+
}
|
|
416
|
+
.content { flex: 1; display: flex; flex-direction: column; justify-content: center; }
|
|
417
|
+
.tag {
|
|
418
|
+
display: inline-block;
|
|
419
|
+
background: #3b82f6;
|
|
346
420
|
color: white;
|
|
347
|
-
|
|
348
|
-
|
|
421
|
+
padding: 8px 16px;
|
|
422
|
+
border-radius: 20px;
|
|
423
|
+
font-size: 18px;
|
|
424
|
+
font-weight: 600;
|
|
425
|
+
margin-bottom: 24px;
|
|
426
|
+
width: fit-content;
|
|
349
427
|
}
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
428
|
+
h1 { color: white; font-size: 56px; font-weight: 700; line-height: 1.2; margin-bottom: 20px; }
|
|
429
|
+
p { color: #94a3b8; font-size: 24px; line-height: 1.5; }
|
|
430
|
+
.avatar {
|
|
431
|
+
width: 200px;
|
|
432
|
+
height: 200px;
|
|
433
|
+
background: linear-gradient(135deg, #06b6d4, #3b82f6);
|
|
434
|
+
border-radius: 100px;
|
|
435
|
+
display: flex;
|
|
436
|
+
align-items: center;
|
|
437
|
+
justify-content: center;
|
|
438
|
+
align-self: center;
|
|
439
|
+
margin-left: 60px;
|
|
353
440
|
}
|
|
441
|
+
.avatar-text { color: white; font-size: 72px; font-weight: 700; }
|
|
354
442
|
</style>
|
|
355
443
|
</head>
|
|
356
444
|
<body>
|
|
357
|
-
<div class="
|
|
358
|
-
<
|
|
359
|
-
|
|
445
|
+
<div class="card">
|
|
446
|
+
<div class="content">
|
|
447
|
+
<span class="tag">Tutorial</span>
|
|
448
|
+
<h1>Getting Started with Rust</h1>
|
|
449
|
+
<p>Learn the fundamentals of Rust programming language with practical examples.</p>
|
|
450
|
+
</div>
|
|
451
|
+
<div class="avatar">
|
|
452
|
+
<span class="avatar-text">RS</span>
|
|
453
|
+
</div>
|
|
360
454
|
</div>
|
|
361
455
|
</body>
|
|
362
456
|
</html>
|
|
363
457
|
```
|
|
458
|
+
</details>
|
|
364
459
|
|
|
365
460
|
## Supported CSS Features
|
|
366
461
|
|
|
@@ -410,20 +505,23 @@ cargo fmt -- --check
|
|
|
410
505
|
|
|
411
506
|
## Releasing
|
|
412
507
|
|
|
413
|
-
Releases are automated via GitHub Actions. To create a new release:
|
|
414
|
-
|
|
415
|
-
1. Update the version in `Cargo.toml`
|
|
416
|
-
2. Create and push a git tag:
|
|
508
|
+
Releases are automated via a release script and GitHub Actions. To create a new release:
|
|
417
509
|
|
|
418
510
|
```bash
|
|
419
|
-
|
|
420
|
-
git push origin v0.1.0
|
|
511
|
+
./scripts/release.sh
|
|
421
512
|
```
|
|
422
513
|
|
|
423
|
-
|
|
514
|
+
The script will:
|
|
515
|
+
1. Verify you're on the main branch with a clean working directory
|
|
516
|
+
2. Check that you're up to date with the remote
|
|
517
|
+
3. Bump the patch version in `Cargo.toml` and `pyproject.toml`
|
|
518
|
+
4. Commit the version changes and create an annotated tag
|
|
519
|
+
5. Push the commit and tag to origin
|
|
520
|
+
|
|
521
|
+
This triggers the GitHub Actions release workflow which:
|
|
424
522
|
- Builds wheels for Linux (x86_64, aarch64) and macOS (x86_64, aarch64)
|
|
425
523
|
- Creates a GitHub Release with all artifacts
|
|
426
|
-
-
|
|
524
|
+
- Publishes to PyPI
|
|
427
525
|
|
|
428
526
|
## License
|
|
429
527
|
|