Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add new option for bytes #25

Merged
merged 9 commits into from
May 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
[package]
name = "resvg_py"
version = "0.1.3"
version = "0.1.4"
edition = "2021"
rust-version = "1.80.0"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[lib]
Expand All @@ -10,7 +11,6 @@ path = "src/rust/lib.rs"
crate-type = ["cdylib"]

[dependencies]
base64 = "0.22.1"
pyo3 = "0.21.2"
resvg = { version = "0.41.0", features = ["raster-images","text"] }
svgtypes = "0.15.0"
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ svg_string = """
</svg>
"""

print(resvg_py.svg_to_base64(svg_string=svg_string))
print(resvg_py.svg_to_bytes(svg_string=svg_string))

```

Expand Down
1 change: 1 addition & 0 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"sphinx.ext.autodoc",
"sphinx.ext.intersphinx",
"sphinx.ext.viewcode",
""
]

templates_path = ["_templates"]
Expand Down
69 changes: 2 additions & 67 deletions docs/resvg.rst
Original file line number Diff line number Diff line change
@@ -1,72 +1,7 @@
Resvg Module
============

.. currentmodule:: resvg_py.svg_to_base64
.. currentmodule:: resvg_py

.. function:: svg_to_base64(svg_str:str,svg_path:str,width:int|None=None,height:int|None=None,zoom:int|None=None,dpi:int|None=None,resources_dir:width:str|None=None,languages:list[str]|None=None,font_size:float|None=None,font_family:str|None=None,serif_family:str|None=None,sans_serif_family:str|None=None,cursive_family:str|None=None,fantasy_family:str|None=None,monospace_family:str|None=None,font_files:list[str]|None=None,font_dirs:list[str]|None=None,shape_rendering:"optimize_speed"|"crisp_edges"|"geometric_precision"="geometric_precision",text_rendering:"optimize_speed"|"optimize_legibility"|"geometric_precision"="optimize_legibility",image_rendering:"optimize_quality"|"optimize_speed"="optimize_quality",background:str|None=None) -> str
.. autofunction:: svg_to_bytes

:param svg_str: A string containing valid svg.
:type svg_str: string

:param svg_path: A path to a valid svg.
:type svg_str: string

:param width: An Integer containing the pixels size for width.
:type width: int or None

:param height: An Integer containing the pixels size for height.
:type height: int or None

:param zoom: An Integer containing the zoom percentage.
:type zoom: int or None

:param dpi: An Integer containing DPI size for the svg rendering.
:type dpi: int or None

:param resources_dir: A directory that contains resources for svg rendering. Such as `foreign objects <https://developer.mozilla.org/en-US/docs/Web/SVG/Element/foreignObject>`_.
:type resources_dir: string or None

:param languages: A list of string containing the languages used for `svg` rendering
:type languages: list[str] or None

:param font_size: An integer describing the font_size.
:type font_size: float or None

:param font_family: A string that describes the font family used in SVG.
:type font_family: str or None

:param serif_family: A string that describes the serif font family used in SVG.
:type serif_family: str or None

:param sans_serif_family: A string that describes the sans serif font family used in SVG.
:type sans_serif_family: str or None

:param cursive_family: A string that describes the cursive font family used in SVG.
:type cursive_family: str or None

:param fantasy_family: A string that describes the fantasy font family used in SVG.
:type fantasy_family: str or None

:param monospace_family: A string that describes the monospace font family used in SVG.
:type monospace_family: str or None

:param font_files: A list of paths that contain the font file.
:type font_files: list[str] or None

:param font_dirs: A list of directories that contain the font file. This parameter will add all the present files in the directory.
:type font_dirs: list[str] or None

:param shape_rendering: The `shape rendering method <https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/shape-rendering>`_ used in resvg. **Defaults to "geometric_precision"**.
:type shape_rendering: "optimize_speed" or "crisp_edges" or **"geometric_precision"**

:param text_rendering: The `text rendering method <https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/text-rendering>`_ used in resvg. **Defaults to "optimize_legibility"**.
:type text_rendering: "optimize_speed" or **"optimize_legibility"** or "geometric_precision"

:param image_rendering: The `image rendering method <https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/image-rendering>`_ used in resvg. **Defaults to "optimize_quality"**.
:type image_rendering: **"optimize_quality"** or "optimize_speed"

:param background: A `CSS color <https://developer.mozilla.org/en-US/docs/Web/CSS/color_value>`_ value that describes the canvas size.
:type background: str or None

:return: base64 encoded string.
:rtype: str
24 changes: 22 additions & 2 deletions docs/usage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,27 @@ We can convert it to `PNG` by:
</svg>
"""

print(resvg_py.svg_to_base64(svg_string=svg_string))
png_bytes: list[bytes] = resvg_py.svg_to_bytes(svg_string=svg_string) # a large list of bytes



In order to convert image to base64:

.. code-block:: python

import resvg_py
import base64

svg_string = """
<svg width="300" height="130" xmlns="http://www.w3.org/2000/svg">
  <rect width="200" height="100" x="10" y="10" rx="20" ry="20" fill="blue" />
</svg>
"""

# a large list of bytes
png_bytes: list[bytes] = resvg_py.svg_to_bytes(svg_string=svg_string)
base64_utf8_str = base64.b64encode(bytes(png_bytes)).decode("utf-8")
print(f"data:image/png;base64,{base64_utf8_str}")


This should return the following **PNG** image (check using inspect element):
Expand All @@ -51,7 +71,7 @@ We can also do something like this :

svg = ... # path to svg file

print(resvg_py.svg_to_base64(svg_path=svg))
print(resvg_py.svg_to_bytes(svg_path=svg))



Expand Down
62 changes: 61 additions & 1 deletion poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "resvg-py"
version = "0.1.3"
version = "0.1.4"
description = ""
authors = ["baseplate-admin <61817579+baseplate-admin@users.noreply.github.com>"]
readme = "README.md"
Expand All @@ -15,6 +15,7 @@ pytest = "^8.1.1"
[tool.poetry.group.docs.dependencies]
sphinx = "^7.2.6"
furo = "^2024.1.29"
sphinx-reload = "^0.2.0"

[build-system]
requires = ["maturin>=1.4,<2.0"]
Expand All @@ -37,3 +38,4 @@ Documentation = "https://resvg-py.readthedocs.io/"

[tool.maturin]
features = ["pyo3/extension-module"]
python-source = "src/python"
54 changes: 54 additions & 0 deletions resvg_py.pyi
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
from typing import Literal

def svg_to_bytes(
svg_string: str | None = None,
svg_path: str | None = None,
width: int | None = None,
height: int | None = None,
resources_dir: str | None = None,
languages: list[str] | None = None,
font_size: int | None = None,
font_family: str | None = None,
serif_family: str | None = None,
sans_serif_family: str | None = None,
cursive_family: str | None = None,
fantasy_family: str | None = None,
monospace_family: str | None = None,
font_files: list[str] | None = None,
font_dirs: list[str] | None = None,
shape_rendering: Literal["optimize_speed"]
| Literal["crisp_edges"]
| Literal["geometric_precision"] = Literal["geometric_precision"],
text_rendering: Literal["optimize_speed"]
| Literal["optimize_legibility"]
| Literal["geometric_precision"] = Literal["optimize_legibility"],
image_rendering: Literal["optimize_quality"] | Literal["optimize_speed"] = Literal[
"optimize_quality"
],
background: str | None = None,
) -> list[bytes]:
"""
:param svg_str: A string containing valid svg.
:param svg_path: A path to a valid svg.
:param width: An Integer containing the pixels size for width.
:param height: An Integer containing the pixels size for height.
:param zoom: An Integer containing the zoom percentage.
:param dpi: An Integer containing DPI size for the svg rendering.
:param resources_dir: A directory that contains resources for svg rendering. Such as `foreign objects <https://developer.mozilla.org/en-US/docs/Web/SVG/Element/foreignObject>`_.
:param languages: A list of string containing the languages used for `svg` rendering
:param font_size: An integer describing the font_size.
:param font_family: A string that describes the font family used in SVG.
:param serif_family: A string that describes the serif font family used in SVG.
:param sans_serif_family: A string that describes the sans serif font family used in SVG.
:param cursive_family: A string that describes the cursive font family used in SVG.
:param fantasy_family: A string that describes the fantasy font family used in SVG.
:param monospace_family: A string that describes the monospace font family used in SVG.
:param font_files: A list of paths that contain the font file.
:param font_dirs: A list of directories that contain the font file. This parameter will add all the present files in the directory.
:param shape_rendering: The `shape rendering method <https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/shape-rendering>`_ used in resvg. **Defaults to "geometric_precision"**.
:param text_rendering: The `text rendering method <https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/text-rendering>`_ used in resvg. **Defaults to "optimize_legibility"**.
:param image_rendering: The `image rendering method <https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/image-rendering>`_ used in resvg. **Defaults to "optimize_quality"**.
:param background: A `CSS color <https://developer.mozilla.org/en-US/docs/Web/CSS/color_value>`_ value that describes the canvas size.
"""

...
11 changes: 5 additions & 6 deletions src/rust/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ Based on
* https://github.com/mrdotb/resvg_nif/blob/master/native/resvg/src/lib.rs
*/

use base64::{engine::general_purpose, Engine as _};
use pyo3::prelude::*;
use resvg;

Expand Down Expand Up @@ -133,8 +132,8 @@ fn resvg_magic(mut options: Opts, svg_string: String) -> Result<Vec<u8>, String>
}

#[pyfunction]
#[pyo3(name = "svg_to_base64")]
fn svg_to_base64(
#[pyo3(name = "svg_to_bytes")]
fn svg_to_bytes(
svg_string: Option<String>,
svg_path: Option<String>,
// Control width, height, zoom, dpi
Expand All @@ -161,7 +160,7 @@ fn svg_to_base64(
image_rendering: Option<String>,
// Background
background: Option<String>,
) -> PyResult<String> {
) -> PyResult<Vec<u8>> {
let mut _svg_string = String::new();

if let Some(svg_string) = svg_string {
Expand Down Expand Up @@ -273,12 +272,12 @@ fn svg_to_base64(
font_dirs,
};
let pixmap = resvg_magic(options, _svg_string.trim().to_owned()).unwrap();
Ok(general_purpose::STANDARD.encode(&pixmap))
Ok(pixmap)
}

/// A Python module implemented in Rust.
#[pymodule]
fn resvg_py(_py: Python, m: &Bound<'_, PyModule>) -> PyResult<()> {
m.add_function(wrap_pyfunction!(svg_to_base64, m)?)?;
m.add_function(wrap_pyfunction!(svg_to_bytes, m)?)?;
Ok(())
}
9 changes: 7 additions & 2 deletions tests/test_complex_camera.py

Large diffs are not rendered by default.

8 changes: 5 additions & 3 deletions tests/test_multiple_layer_svg.py

Large diffs are not rendered by default.

7 changes: 5 additions & 2 deletions tests/test_normal_shape.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import resvg_py
import base64

svg_string = """
<svg width="300" height="130" xmlns="http://www.w3.org/2000/svg">
Expand All @@ -8,8 +9,10 @@


def test_rectangle():
base64 = resvg_py.svg_to_base64(svg_string=svg_string)
_base64 = base64.b64encode(
bytes(resvg_py.svg_to_bytes(svg_string=svg_string))
).decode("utf-8")
assert (
base64
_base64
== "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"
)
Loading
Loading