mirror of
https://github.com/visioncortex/vtracer.git
synced 2026-09-27 06:21:23 -07:00
Move code around
This commit is contained in:
@@ -7,9 +7,6 @@ name: CI
|
|||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
|
||||||
- main
|
|
||||||
- master
|
|
||||||
tags:
|
tags:
|
||||||
- '*'
|
- '*'
|
||||||
pull_request:
|
pull_request:
|
||||||
|
|||||||
+4
-10
@@ -1,7 +1,7 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "vtracer"
|
name = "vtracer"
|
||||||
version = "0.6.3"
|
version = "0.6.3"
|
||||||
authors = ["Chris Tsang <tyt2y7@gmail.com>"]
|
authors = ["Chris Tsang <chris.2y3@outlook.com>"]
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
description = "A cmd app to convert images into vector graphics."
|
description = "A cmd app to convert images into vector graphics."
|
||||||
license = "MIT OR Apache-2.0"
|
license = "MIT OR Apache-2.0"
|
||||||
@@ -15,13 +15,7 @@ clap = "2.33.3"
|
|||||||
image = "0.23.10"
|
image = "0.23.10"
|
||||||
visioncortex = { version = "0.8.0" }
|
visioncortex = { version = "0.8.0" }
|
||||||
fastrand = "1.8"
|
fastrand = "1.8"
|
||||||
pyo3 = "0.19.0"
|
pyo3 = { version = "0.19.0", optional = true }
|
||||||
|
|
||||||
[lib]
|
[features]
|
||||||
name = "vtracer"
|
python-binding = ["pyo3"]
|
||||||
crate-type = ["cdylib"]
|
|
||||||
path = "src/lib.rs"
|
|
||||||
|
|
||||||
[[bin]]
|
|
||||||
name = "vtracer"
|
|
||||||
path = "src/main.rs"
|
|
||||||
@@ -2,8 +2,8 @@
|
|||||||
name = "vtracer"
|
name = "vtracer"
|
||||||
version = "0.6.3"
|
version = "0.6.3"
|
||||||
description = "Python bindings for the Rust Vtracer raster-to-vector library"
|
description = "Python bindings for the Rust Vtracer raster-to-vector library"
|
||||||
authors = [ { name = "Chris Tsang", email = "tyt2y7@gmail.com" } ]
|
authors = [ { name = "Chris Tsang", email = "chris.2y3@outlook.com" } ]
|
||||||
readme = "vtracer/README_PY.md"
|
readme = "vtracer/README.md"
|
||||||
requires-python = ">=3.7"
|
requires-python = ">=3.7"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
classifiers = [
|
classifiers = [
|
||||||
@@ -25,4 +25,4 @@ build-backend = "maturin"
|
|||||||
[tool.maturin]
|
[tool.maturin]
|
||||||
features = ["pyo3/extension-module"]
|
features = ["pyo3/extension-module"]
|
||||||
compatibility = "linux"
|
compatibility = "linux"
|
||||||
sdist-include = ["../LICENSE", "../README_PY.md"]
|
sdist-include = ["../LICENSE", "../README.md"]
|
||||||
+1
-81
@@ -1,9 +1,8 @@
|
|||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::{fs::File, io::Write};
|
use std::{fs::File, io::Write};
|
||||||
use pyo3::prelude::*;
|
|
||||||
|
|
||||||
use fastrand::Rng;
|
use fastrand::Rng;
|
||||||
use visioncortex::{Color, ColorImage, ColorName, PathSimplifyMode};
|
use visioncortex::{Color, ColorImage, ColorName};
|
||||||
use visioncortex::color_clusters::{Runner, RunnerConfig, KeyingAction, HIERARCHICAL_MAX};
|
use visioncortex::color_clusters::{Runner, RunnerConfig, KeyingAction, HIERARCHICAL_MAX};
|
||||||
use super::config::{Config, ColorMode, Hierarchical, ConverterConfig};
|
use super::config::{Config, ColorMode, Hierarchical, ConverterConfig};
|
||||||
use super::svg::SvgFile;
|
use super::svg::SvgFile;
|
||||||
@@ -225,84 +224,5 @@ fn write_svg(svg: SvgFile, output_path: PathBuf) -> Result<(), String> {
|
|||||||
|
|
||||||
write!(&mut out_file, "{}", svg).expect("failed to write file.");
|
write!(&mut out_file, "{}", svg).expect("failed to write file.");
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
// ==================
|
|
||||||
// = PYTHON BINDING =
|
|
||||||
// ==================
|
|
||||||
#[pyfunction]
|
|
||||||
fn convert_image_to_svg_py( image_path: &str,
|
|
||||||
out_path: &str,
|
|
||||||
colormode: Option<&str>, // "color" or "binary"
|
|
||||||
hierarchical: Option<&str>, // "stacked" or "cutout"
|
|
||||||
mode: Option<&str>, // "polygon", "spline", "none"
|
|
||||||
filter_speckle: Option<usize>, // default: 4
|
|
||||||
color_precision: Option<i32>, // default: 6
|
|
||||||
layer_difference: Option<i32>, // default: 16
|
|
||||||
corner_threshold: Option<i32>, // default: 60
|
|
||||||
length_threshold: Option<f64>, // in [3.5, 10] default: 4.0
|
|
||||||
max_iterations: Option<usize>, // default: 10
|
|
||||||
splice_threshold: Option<i32>, // default: 45
|
|
||||||
path_precision: Option<u32> // default: 8
|
|
||||||
) -> PyResult<()> {
|
|
||||||
let input_path = PathBuf::from(image_path);
|
|
||||||
let output_path = PathBuf::from(out_path);
|
|
||||||
|
|
||||||
// TODO: enforce color mode with an enum so that we only
|
|
||||||
// accept the strings 'color' or 'binary'
|
|
||||||
let color_mode = match colormode.unwrap_or("color") {
|
|
||||||
"color" => ColorMode::Color,
|
|
||||||
"binary" => ColorMode::Binary,
|
|
||||||
_ => ColorMode::Color,
|
|
||||||
};
|
|
||||||
|
|
||||||
let hierarchical = match hierarchical.unwrap_or("stacked") {
|
|
||||||
"stacked" => Hierarchical::Stacked,
|
|
||||||
"cutout" => Hierarchical::Cutout,
|
|
||||||
_ => Hierarchical::Stacked,
|
|
||||||
};
|
|
||||||
|
|
||||||
let mode = match mode.unwrap_or("spline") {
|
|
||||||
"spline" => PathSimplifyMode::Spline,
|
|
||||||
"polygon" => PathSimplifyMode::Polygon,
|
|
||||||
"none" => PathSimplifyMode::None,
|
|
||||||
_ => PathSimplifyMode::Spline,
|
|
||||||
};
|
|
||||||
|
|
||||||
let filter_speckle = filter_speckle.unwrap_or(4);
|
|
||||||
let color_precision = color_precision.unwrap_or(6);
|
|
||||||
let layer_difference = layer_difference.unwrap_or(16);
|
|
||||||
let corner_threshold = corner_threshold.unwrap_or(60);
|
|
||||||
let length_threshold = length_threshold.unwrap_or(4.0);
|
|
||||||
let splice_threshold = splice_threshold.unwrap_or(45);
|
|
||||||
let max_iterations = max_iterations.unwrap_or(10);
|
|
||||||
|
|
||||||
let config = Config {
|
|
||||||
input_path,
|
|
||||||
output_path,
|
|
||||||
color_mode,
|
|
||||||
hierarchical,
|
|
||||||
filter_speckle,
|
|
||||||
color_precision,
|
|
||||||
layer_difference,
|
|
||||||
mode,
|
|
||||||
corner_threshold,
|
|
||||||
length_threshold,
|
|
||||||
max_iterations,
|
|
||||||
splice_threshold,
|
|
||||||
path_precision,
|
|
||||||
..Default::default()
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
convert_image_to_svg(config).unwrap();
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A Python module implemented in Rust.
|
|
||||||
#[pymodule]
|
|
||||||
fn vtracer(_py: Python, m: &PyModule) -> PyResult<()> {
|
|
||||||
m.add_function(wrap_pyfunction!(convert_image_to_svg_py, m)?)?;
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
+4
-1
@@ -11,7 +11,10 @@
|
|||||||
mod config;
|
mod config;
|
||||||
mod converter;
|
mod converter;
|
||||||
mod svg;
|
mod svg;
|
||||||
|
mod python;
|
||||||
|
|
||||||
pub use config::*;
|
pub use config::*;
|
||||||
pub use converter::*;
|
pub use converter::*;
|
||||||
pub use svg::*;
|
pub use svg::*;
|
||||||
|
#[cfg(feature = "python-binding")]
|
||||||
|
pub use python::*;
|
||||||
+3
-5
@@ -1,10 +1,8 @@
|
|||||||
mod config;
|
use vtracer::{Config, convert_image_to_svg};
|
||||||
mod converter;
|
|
||||||
mod svg;
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let config = config::Config::from_args();
|
let config = Config::from_args();
|
||||||
let result = converter::convert_image_to_svg(config);
|
let result = convert_image_to_svg(config);
|
||||||
match result {
|
match result {
|
||||||
Ok(()) => {
|
Ok(()) => {
|
||||||
println!("Conversion successful.");
|
println!("Conversion successful.");
|
||||||
|
|||||||
@@ -0,0 +1,81 @@
|
|||||||
|
use pyo3::prelude::*;
|
||||||
|
|
||||||
|
use visioncortex::{PathSimplifyMode};
|
||||||
|
use super::converter::*;
|
||||||
|
|
||||||
|
/// Python binding
|
||||||
|
#[pyfunction]
|
||||||
|
fn convert_image_to_svg_py( image_path: &str,
|
||||||
|
out_path: &str,
|
||||||
|
colormode: Option<&str>, // "color" or "binary"
|
||||||
|
hierarchical: Option<&str>, // "stacked" or "cutout"
|
||||||
|
mode: Option<&str>, // "polygon", "spline", "none"
|
||||||
|
filter_speckle: Option<usize>, // default: 4
|
||||||
|
color_precision: Option<i32>, // default: 6
|
||||||
|
layer_difference: Option<i32>, // default: 16
|
||||||
|
corner_threshold: Option<i32>, // default: 60
|
||||||
|
length_threshold: Option<f64>, // in [3.5, 10] default: 4.0
|
||||||
|
max_iterations: Option<usize>, // default: 10
|
||||||
|
splice_threshold: Option<i32>, // default: 45
|
||||||
|
path_precision: Option<u32> // default: 8
|
||||||
|
) -> PyResult<()> {
|
||||||
|
let input_path = PathBuf::from(image_path);
|
||||||
|
let output_path = PathBuf::from(out_path);
|
||||||
|
|
||||||
|
// TODO: enforce color mode with an enum so that we only
|
||||||
|
// accept the strings 'color' or 'binary'
|
||||||
|
let color_mode = match colormode.unwrap_or("color") {
|
||||||
|
"color" => ColorMode::Color,
|
||||||
|
"binary" => ColorMode::Binary,
|
||||||
|
_ => ColorMode::Color,
|
||||||
|
};
|
||||||
|
|
||||||
|
let hierarchical = match hierarchical.unwrap_or("stacked") {
|
||||||
|
"stacked" => Hierarchical::Stacked,
|
||||||
|
"cutout" => Hierarchical::Cutout,
|
||||||
|
_ => Hierarchical::Stacked,
|
||||||
|
};
|
||||||
|
|
||||||
|
let mode = match mode.unwrap_or("spline") {
|
||||||
|
"spline" => PathSimplifyMode::Spline,
|
||||||
|
"polygon" => PathSimplifyMode::Polygon,
|
||||||
|
"none" => PathSimplifyMode::None,
|
||||||
|
_ => PathSimplifyMode::Spline,
|
||||||
|
};
|
||||||
|
|
||||||
|
let filter_speckle = filter_speckle.unwrap_or(4);
|
||||||
|
let color_precision = color_precision.unwrap_or(6);
|
||||||
|
let layer_difference = layer_difference.unwrap_or(16);
|
||||||
|
let corner_threshold = corner_threshold.unwrap_or(60);
|
||||||
|
let length_threshold = length_threshold.unwrap_or(4.0);
|
||||||
|
let splice_threshold = splice_threshold.unwrap_or(45);
|
||||||
|
let max_iterations = max_iterations.unwrap_or(10);
|
||||||
|
|
||||||
|
let config = Config {
|
||||||
|
input_path,
|
||||||
|
output_path,
|
||||||
|
color_mode,
|
||||||
|
hierarchical,
|
||||||
|
filter_speckle,
|
||||||
|
color_precision,
|
||||||
|
layer_difference,
|
||||||
|
mode,
|
||||||
|
corner_threshold,
|
||||||
|
length_threshold,
|
||||||
|
max_iterations,
|
||||||
|
splice_threshold,
|
||||||
|
path_precision,
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
convert_image_to_svg(config).unwrap();
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A Python module implemented in Rust.
|
||||||
|
#[pymodule]
|
||||||
|
fn vtracer(_py: Python, m: &PyModule) -> PyResult<()> {
|
||||||
|
m.add_function(wrap_pyfunction!(convert_image_to_svg_py, m)?)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "vtracer-webapp"
|
name = "vtracer-webapp"
|
||||||
version = "0.4.0"
|
version = "0.4.0"
|
||||||
authors = ["Chris Tsang <tyt2y7@gmail.com>"]
|
authors = ["Chris Tsang <chris.2y3@outlook.com>"]
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
description = "A web app to convert images into vector graphics."
|
description = "A web app to convert images into vector graphics."
|
||||||
license = "MIT OR Apache-2.0"
|
license = "MIT OR Apache-2.0"
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
"name": "vtracer-app",
|
"name": "vtracer-app",
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"description": "VTracer Webapp",
|
"description": "VTracer Webapp",
|
||||||
"author": "Chris Tsang <tyt2y7@gmail.com>",
|
"author": "Chris Tsang <chris.2y3@outlook.com>",
|
||||||
"license": "proprietary",
|
"license": "proprietary",
|
||||||
"private": true,
|
"private": true,
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
|
|||||||
Reference in New Issue
Block a user