feat: improved color handling
This commit is contained in:
parent
29252c5c03
commit
dfb6e0789e
6 changed files with 76 additions and 18 deletions
|
@ -4,12 +4,12 @@ use geo::{polygon, LineString, MultiLineString, MultiPolygon, Polygon};
|
||||||
use rand::rngs::StdRng;
|
use rand::rngs::StdRng;
|
||||||
use rand::{Rng, SeedableRng};
|
use rand::{Rng, SeedableRng};
|
||||||
|
|
||||||
use crate::context::commandline::Opt;
|
use crate::context::command_line_options::Opt;
|
||||||
use crate::context::palette::Palette;
|
use crate::context::palette::Palette;
|
||||||
use crate::context::renderer::{PngRenderContainer, RenderContainer, SvgRenderContainer};
|
use crate::context::renderer::{PngRenderContainer, RenderContainer, SvgRenderContainer};
|
||||||
use iso8601::Date::*;
|
use iso8601::Date::*;
|
||||||
|
|
||||||
pub mod commandline;
|
pub mod command_line_options;
|
||||||
pub mod palette;
|
pub mod palette;
|
||||||
pub mod renderer;
|
pub mod renderer;
|
||||||
|
|
||||||
|
@ -116,6 +116,7 @@ impl Context {
|
||||||
let opt = Opt::get_command_line_arguments();
|
let opt = Opt::get_command_line_arguments();
|
||||||
let line_size = opt.line_size.clone();
|
let line_size = opt.line_size.clone();
|
||||||
|
|
||||||
|
// todo : this is not correct
|
||||||
let mm = 3.779527547619048; // calculated with inkscape 1587.40157 (px) / 420 (mm) (from a3)
|
let mm = 3.779527547619048; // calculated with inkscape 1587.40157 (px) / 420 (mm) (from a3)
|
||||||
let (mut height, mut width) = match opt.format {
|
let (mut height, mut width) = match opt.format {
|
||||||
None => (f64::from(opt.height.clone()), f64::from(opt.width.clone())),
|
None => (f64::from(opt.height.clone()), f64::from(opt.width.clone())),
|
||||||
|
@ -150,11 +151,12 @@ impl Context {
|
||||||
let mut rng = StdRng::seed_from_u64(random_seed);
|
let mut rng = StdRng::seed_from_u64(random_seed);
|
||||||
|
|
||||||
// color
|
// color
|
||||||
let y: f32 = rng.gen(); // generates a float between 0 and 1
|
let main_color = Palette::random_color(StdRng::seed_from_u64(rng.gen()));
|
||||||
let hue: f32 = y * 360.0;
|
let palette = match &opt.color_type[..] {
|
||||||
let saturation: f32 = f32::max(rng.gen(), 0.6);
|
"bright_on_dark" => Palette::bright_on_dark(main_color),
|
||||||
let value: f32 = f32::max(rng.gen(), 0.6);
|
"dark_on_bright" => Palette::dark_on_bright(main_color),
|
||||||
let palette = Palette::dark_on_bright(Palette::color(hue, saturation, value));
|
_ => Palette::bright_on_dark(main_color),
|
||||||
|
};
|
||||||
|
|
||||||
let render_container: Box<dyn RenderContainer> = if opt.output_type == "svg" {
|
let render_container: Box<dyn RenderContainer> = if opt.output_type == "svg" {
|
||||||
let svg_surface = SvgSurface::new(
|
let svg_surface = SvgSurface::new(
|
||||||
|
|
|
@ -53,6 +53,14 @@ pub struct Opt {
|
||||||
/// (must be ISO8601)
|
/// (must be ISO8601)
|
||||||
#[structopt(long = "random-date", conflicts_with = "random-seed", parse(try_from_str = iso8601::date))]
|
#[structopt(long = "random-date", conflicts_with = "random-seed", parse(try_from_str = iso8601::date))]
|
||||||
pub random_seed_date: Option<iso8601::Date>,
|
pub random_seed_date: Option<iso8601::Date>,
|
||||||
|
|
||||||
|
/// how to use color palette to draw image
|
||||||
|
#[structopt(
|
||||||
|
long,
|
||||||
|
possible_values=&["dark_on_bright", "bright_on_dark"],
|
||||||
|
default_value="dark_on_bright"
|
||||||
|
)]
|
||||||
|
pub color_type: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Opt {
|
impl Opt {
|
|
@ -1,5 +1,6 @@
|
||||||
//! Color palate generator.
|
//! Color palate generator.
|
||||||
|
|
||||||
|
use crate::RandomExt;
|
||||||
use palette::rgb::Rgb;
|
use palette::rgb::Rgb;
|
||||||
use palette::FromColor;
|
use palette::FromColor;
|
||||||
use palette::Hsl;
|
use palette::Hsl;
|
||||||
|
@ -19,21 +20,18 @@ impl Palette {
|
||||||
/// and to color less.
|
/// and to color less.
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub fn random_color(mut rng: StdRng) -> Rgb {
|
pub fn random_color(mut rng: StdRng) -> Rgb {
|
||||||
//let mut rng = rand::thread_rng();
|
let hue: f32 = rng.gen_interval(0., 360.);
|
||||||
let y: f32 = rng.gen(); // generates a float between 0 and 1
|
let saturation: f32 = rng.gen_interval(0.9, 1.0);
|
||||||
let hue: f32 = y * 360.0;
|
let value: f32 = rng.gen_interval(0.8, 1.0);
|
||||||
let saturation: f32 = f32::max(rng.gen(), 0.6);
|
|
||||||
let value: f32 = f32::max(rng.gen(), 0.6);
|
|
||||||
//Rgb::from_linear(Hsv::new(hue, saturation, value).into_rgb())
|
|
||||||
Palette::color(hue, saturation, value)
|
Palette::color(hue, saturation, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn color(hue: f32, saturation: f32, value: f32) -> Rgb {
|
pub fn color(hue: f32, saturation: f32, value: f32) -> Rgb {
|
||||||
Rgb::from_linear(Hsv::new(hue, saturation, value).into_rgb())
|
Rgb::from_linear(Hsv::new(hue, saturation, value).into_rgb())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// generate a palette from the tint and shade palette
|
/// generate a palette from the tint and shade palette
|
||||||
/// algorithm. choose a dark background and a bright filling color
|
/// algorithm. choose a dark background, and a bright filling color
|
||||||
#[allow(dead_code)]
|
|
||||||
pub fn bright_on_dark(input: Rgb) -> Palette {
|
pub fn bright_on_dark(input: Rgb) -> Palette {
|
||||||
let tint_and_shade_palette = TintAndShadePalette::create(input);
|
let tint_and_shade_palette = TintAndShadePalette::create(input);
|
||||||
Palette {
|
Palette {
|
||||||
|
@ -43,7 +41,7 @@ impl Palette {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// generate a palette from the tint and shade palette
|
/// generate a palette from the tint and shade palette
|
||||||
/// algorithm. choose a bright background and a dark filling color
|
/// algorithm. choose a bright background, and a dark filling color
|
||||||
pub fn dark_on_bright(input: Rgb) -> Palette {
|
pub fn dark_on_bright(input: Rgb) -> Palette {
|
||||||
let tint_and_shade_palette = TintAndShadePalette::create(input);
|
let tint_and_shade_palette = TintAndShadePalette::create(input);
|
||||||
Palette {
|
Palette {
|
||||||
|
@ -54,8 +52,7 @@ impl Palette {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The Tint and Shade Palette from https://gitlab.com/cameralibre/tint-and-shade
|
/// The Tint and Shade Palette from https://gitlab.com/cameralibre/tint-and-shade
|
||||||
/// Thank you Sam
|
/// Thank you, Sam
|
||||||
#[allow(dead_code)]
|
|
||||||
struct TintAndShadePalette {
|
struct TintAndShadePalette {
|
||||||
base_color: Rgb,
|
base_color: Rgb,
|
||||||
base_tint_30: Rgb,
|
base_tint_30: Rgb,
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
pub(crate) mod merge_ext;
|
pub(crate) mod merge_ext;
|
||||||
|
pub(crate) mod random_ext;
|
||||||
pub(crate) mod scale_ext;
|
pub(crate) mod scale_ext;
|
||||||
pub(crate) mod translate_ext;
|
pub(crate) mod translate_ext;
|
||||||
|
|
49
src/extensions/random_ext.rs
Normal file
49
src/extensions/random_ext.rs
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
use rand::rngs::StdRng;
|
||||||
|
use rand::Rng;
|
||||||
|
|
||||||
|
pub trait RandomExt<T> {
|
||||||
|
fn gen_interval(&mut self, min: T, max: T) -> T;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RandomExt<f32> for StdRng {
|
||||||
|
fn gen_interval(&mut self, min: f32, max: f32) -> f32 {
|
||||||
|
if min == max {
|
||||||
|
return min;
|
||||||
|
}
|
||||||
|
let minimum = f32::min(min, max);
|
||||||
|
let maximum = f32::max(min, max);
|
||||||
|
let diff = maximum - minimum;
|
||||||
|
let x: f32 = self.gen();
|
||||||
|
x * diff + minimum
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RandomExt<f64> for StdRng {
|
||||||
|
fn gen_interval(&mut self, min: f64, max: f64) -> f64 {
|
||||||
|
if min == max {
|
||||||
|
return min;
|
||||||
|
}
|
||||||
|
let minimum = f64::min(min, max);
|
||||||
|
let maximum = f64::max(min, max);
|
||||||
|
let diff = maximum - minimum;
|
||||||
|
let x: f64 = self.gen();
|
||||||
|
x * diff + minimum
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test {
|
||||||
|
use rand::prelude::StdRng;
|
||||||
|
use rand::{Rng, SeedableRng};
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_gen() {
|
||||||
|
let random_seed = rand::random();
|
||||||
|
let mut rng = StdRng::seed_from_u64(random_seed);
|
||||||
|
for _ in 0..1000 {
|
||||||
|
let random_number: f64 = rng.gen();
|
||||||
|
assert!(random_number < 1.);
|
||||||
|
assert!(random_number > 0.);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,6 +3,7 @@ pub use crate::context::Context;
|
||||||
|
|
||||||
mod extensions;
|
mod extensions;
|
||||||
pub use crate::extensions::merge_ext::MergeExt;
|
pub use crate::extensions::merge_ext::MergeExt;
|
||||||
|
pub use crate::extensions::random_ext::RandomExt;
|
||||||
pub use crate::extensions::scale_ext::ScaleExt;
|
pub use crate::extensions::scale_ext::ScaleExt;
|
||||||
pub use crate::extensions::translate_ext::TranslateExt;
|
pub use crate::extensions::translate_ext::TranslateExt;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue