svg2img 0.2.2 → 0.2.4
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.
- checksums.yaml +4 -4
- data/Cargo.toml +4 -0
- data/README.md +1 -0
- data/ext/svg2img/Cargo.toml +3 -3
- data/ext/svg2img/src/lib.rs +49 -7
- data/lib/svg2img/version.rb +1 -1
- data/tmp/arm64-darwin23/stage/Cargo.toml +4 -0
- data/tmp/arm64-darwin23/stage/ext/svg2img/Cargo.toml +3 -3
- data/tmp/arm64-darwin23/stage/tmp/arm64-darwin23/stage/Cargo.toml +4 -0
- data/tmp/arm64-darwin23/stage/tmp/arm64-darwin23/stage/ext/svg2img/Cargo.toml +3 -3
- data/tmp/arm64-darwin23/stage/tmp/arm64-darwin23/stage/tmp/arm64-darwin23/stage/Cargo.lock +1607 -0
- data/tmp/arm64-darwin23/stage/tmp/arm64-darwin23/stage/tmp/arm64-darwin23/stage/Cargo.toml +11 -0
- data/tmp/arm64-darwin23/stage/tmp/arm64-darwin23/stage/tmp/arm64-darwin23/stage/ext/svg2img/Cargo.toml +17 -0
- metadata +4 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 73a2ea65b81532ded264b2ec92e94d3ac146fda59529c2501625e1ac0fa6472c
|
4
|
+
data.tar.gz: 1a378f708361feec86a69733148206d175cb58b354f4f140ab7f2e5fa10faf9d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e0ae235c6a4addf8c2495bd2674f1508359ec58d08d77d1944587cab178dee8a32657f5b6c77c68a1a541a4a7b01889d9eae8980b18cd1dd96235bd1f8d55899
|
7
|
+
data.tar.gz: b7af313204aaac5b70b08b614cacced3eb56d35c54febbb4da93c316842f724236729ab41b12575779284e60e36cacf7dc17df02bca4269b1f002f6ef76f5f81
|
data/Cargo.toml
CHANGED
data/README.md
CHANGED
@@ -73,6 +73,7 @@ send_data(png_data, type: 'image/png', disposition: 'inline')
|
|
73
73
|
- `format` - output format, one of `:png`, `:jpg`, `:webp`, `:gif`
|
74
74
|
- `output_path` - path to the output image. If not provided, a temporary file will be created and the path to it will be returned.
|
75
75
|
- `size` - size of the output image as a proc that receives the width and height of the SVG and returns an array with the width and height of the output image. If the provides size has a different aspect ratio than the SVG, the image will be resized to fit in the center of the provided size. If not provided, the output image will have the same size as the SVG.
|
76
|
+
- `super_sampling` - supersample factor. The output image will be rendered `super_sampling` times larger than the SVG and then resized to the desired size. This can be used to improve the quality of the output image. Default is 2. Must be a power of 2. 1 means no super sampling.
|
76
77
|
|
77
78
|
## Development
|
78
79
|
|
data/ext/svg2img/Cargo.toml
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
[package]
|
2
|
-
name = "svg2img"
|
3
|
-
version = "0.1.0"
|
4
|
-
edition = "2021"
|
5
2
|
authors = ["Orvar Segerström <orvarsegerstrom@gmail.com>"]
|
3
|
+
edition = "2021"
|
6
4
|
license = "MIT"
|
5
|
+
name = "svg2img"
|
7
6
|
publish = false
|
7
|
+
version = "0.1.0"
|
8
8
|
|
9
9
|
[lib]
|
10
10
|
crate-type = ["cdylib"]
|
data/ext/svg2img/src/lib.rs
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
use anyhow::Context;
|
2
|
-
use image::{DynamicImage, ImageBuffer};
|
2
|
+
use image::{DynamicImage, ImageBuffer, ImageEncoder};
|
3
3
|
use magnus::{block::Proc, function, prelude::*, Error, Ruby};
|
4
4
|
use std::panic::{self, AssertUnwindSafe};
|
5
5
|
|
@@ -27,12 +27,23 @@ fn process_svg_rb(svg: String, options: magnus::RHash) -> Result<String, magnus:
|
|
27
27
|
}
|
28
28
|
};
|
29
29
|
}
|
30
|
+
|
31
|
+
let super_sampling = get_option::<u32>(&options, "super_sampling")?.unwrap_or(2);
|
32
|
+
// super_sampling must me a power of 2
|
33
|
+
if super_sampling == 0 || super_sampling & (super_sampling - 1) != 0 {
|
34
|
+
return Err(magnus::Error::new(
|
35
|
+
magnus::exception::arg_error(),
|
36
|
+
"svg2img: Invalid super_sampling value, must be a power of 2",
|
37
|
+
));
|
38
|
+
}
|
39
|
+
|
30
40
|
let options = Options {
|
31
41
|
size: get_option::<Proc>(&options, "size")?
|
32
42
|
.map(convert_size_proc)
|
33
43
|
.unwrap_or_else(default_size),
|
34
|
-
format,
|
35
44
|
output_path: get_option(&options, "output_path")?,
|
45
|
+
format,
|
46
|
+
super_sampling,
|
36
47
|
};
|
37
48
|
process_svg(svg, options)
|
38
49
|
.map_err(|err| magnus::Error::new(magnus::exception::runtime_error(), format!("{err:?}")))
|
@@ -97,10 +108,17 @@ struct Options {
|
|
97
108
|
size: ProcessSize,
|
98
109
|
format: image::ImageFormat,
|
99
110
|
output_path: Option<String>,
|
111
|
+
super_sampling: u32,
|
100
112
|
}
|
101
113
|
|
102
114
|
fn process_svg(svg: String, options: Options) -> Result<String, anyhow::Error> {
|
103
|
-
let
|
115
|
+
let image = image_from_svg(svg.as_bytes(), options.size, options.super_sampling)?;
|
116
|
+
|
117
|
+
let mut image = image.resize_exact(
|
118
|
+
image.width() / options.super_sampling,
|
119
|
+
image.height() / options.super_sampling,
|
120
|
+
image::imageops::FilterType::Lanczos3,
|
121
|
+
);
|
104
122
|
|
105
123
|
if options.format == image::ImageFormat::Jpeg {
|
106
124
|
// Convert from rgba8 to rgb8
|
@@ -109,9 +127,27 @@ fn process_svg(svg: String, options: Options) -> Result<String, anyhow::Error> {
|
|
109
127
|
|
110
128
|
let mut buf = Vec::new();
|
111
129
|
let mut cursor = std::io::Cursor::new(&mut buf);
|
112
|
-
|
113
|
-
|
114
|
-
|
130
|
+
match options.format {
|
131
|
+
image::ImageFormat::Png => {
|
132
|
+
image::codecs::png::PngEncoder::new_with_quality(
|
133
|
+
&mut cursor,
|
134
|
+
image::codecs::png::CompressionType::Best,
|
135
|
+
image::codecs::png::FilterType::Adaptive,
|
136
|
+
)
|
137
|
+
.write_image(
|
138
|
+
&image.to_rgba8().into_raw(),
|
139
|
+
image.width(),
|
140
|
+
image.height(),
|
141
|
+
image.color().into(),
|
142
|
+
)
|
143
|
+
.context("Failed to encode PNG")?;
|
144
|
+
}
|
145
|
+
_ => {
|
146
|
+
image
|
147
|
+
.write_to(&mut cursor, options.format)
|
148
|
+
.context("Failed to write image to buffer")?;
|
149
|
+
}
|
150
|
+
};
|
115
151
|
|
116
152
|
let output_path = options.output_path.unwrap_or_else(|| {
|
117
153
|
let random_filename = format!(
|
@@ -133,7 +169,11 @@ fn process_svg(svg: String, options: Options) -> Result<String, anyhow::Error> {
|
|
133
169
|
Ok(output_path)
|
134
170
|
}
|
135
171
|
|
136
|
-
fn image_from_svg(
|
172
|
+
fn image_from_svg(
|
173
|
+
bytes: &[u8],
|
174
|
+
size: ProcessSize,
|
175
|
+
super_sampling: u32,
|
176
|
+
) -> Result<DynamicImage, anyhow::Error> {
|
137
177
|
let svg = resvg::usvg::Tree::from_data(bytes, &resvg::usvg::Options::default())
|
138
178
|
.context("Failed to parse SVG")?;
|
139
179
|
let svg_width = svg.size().width();
|
@@ -141,6 +181,8 @@ fn image_from_svg(bytes: &[u8], size: ProcessSize) -> Result<DynamicImage, anyho
|
|
141
181
|
let svg_ratio = svg_width / svg_height;
|
142
182
|
|
143
183
|
let (image_width, image_height) = size(svg_width as u32, svg_height as u32)?;
|
184
|
+
let image_width = image_width * super_sampling;
|
185
|
+
let image_height = image_height * super_sampling;
|
144
186
|
let image_ratio = image_width as f32 / image_height as f32;
|
145
187
|
|
146
188
|
let scale = if svg_ratio > image_ratio {
|
data/lib/svg2img/version.rb
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
[package]
|
2
|
-
name = "svg2img"
|
3
|
-
version = "0.1.0"
|
4
|
-
edition = "2021"
|
5
2
|
authors = ["Orvar Segerström <orvarsegerstrom@gmail.com>"]
|
3
|
+
edition = "2021"
|
6
4
|
license = "MIT"
|
5
|
+
name = "svg2img"
|
7
6
|
publish = false
|
7
|
+
version = "0.1.0"
|
8
8
|
|
9
9
|
[lib]
|
10
10
|
crate-type = ["cdylib"]
|
@@ -1,10 +1,10 @@
|
|
1
1
|
[package]
|
2
|
-
name = "svg2img"
|
3
|
-
version = "0.1.0"
|
4
|
-
edition = "2021"
|
5
2
|
authors = ["Orvar Segerström <orvarsegerstrom@gmail.com>"]
|
3
|
+
edition = "2021"
|
6
4
|
license = "MIT"
|
5
|
+
name = "svg2img"
|
7
6
|
publish = false
|
7
|
+
version = "0.1.0"
|
8
8
|
|
9
9
|
[lib]
|
10
10
|
crate-type = ["cdylib"]
|