feat: improved color handling

develop
Ingolf Wagner 2021-04-16 16:17:57 +02:00
parent 29252c5c03
commit dfb6e0789e
Signed by: palo
GPG Key ID: 76BF5F1928B9618B
6 changed files with 76 additions and 18 deletions

View File

@ -4,12 +4,12 @@ use geo::{polygon, LineString, MultiLineString, MultiPolygon, Polygon};
use rand::rngs::StdRng;
use rand::{Rng, SeedableRng};
use crate::context::commandline::Opt;
use crate::context::command_line_options::Opt;
use crate::context::palette::Palette;
use crate::context::renderer::{PngRenderContainer, RenderContainer, SvgRenderContainer};
use iso8601::Date::*;
pub mod commandline;
pub mod command_line_options;
pub mod palette;
pub mod renderer;
@ -116,6 +116,7 @@ impl Context {
let opt = Opt::get_command_line_arguments();
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 (mut height, mut width) = match opt.format {
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);
// color
let y: f32 = rng.gen(); // generates a float between 0 and 1
let hue: f32 = y * 360.0;
let saturation: f32 = f32::max(rng.gen(), 0.6);
let value: f32 = f32::max(rng.gen(), 0.6);
let palette = Palette::dark_on_bright(Palette::color(hue, saturation, value));
let main_color = Palette::random_color(StdRng::seed_from_u64(rng.gen()));
let palette = match &opt.color_type[..] {
"bright_on_dark" => Palette::bright_on_dark(main_color),
"dark_on_bright" => Palette::dark_on_bright(main_color),
_ => Palette::bright_on_dark(main_color),
};
let render_container: Box<dyn RenderContainer> = if opt.output_type == "svg" {
let svg_surface = SvgSurface::new(

View File

@ -53,6 +53,14 @@ pub struct Opt {
/// (must be ISO8601)
#[structopt(long = "random-date", conflicts_with = "random-seed", parse(try_from_str = 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 {

View File

@ -1,5 +1,6 @@
//! Color palate generator.
use crate::RandomExt;
use palette::rgb::Rgb;
use palette::FromColor;
use palette::Hsl;
@ -19,21 +20,18 @@ impl Palette {
/// and to color less.
#[allow(dead_code)]
pub fn random_color(mut rng: StdRng) -> Rgb {
//let mut rng = rand::thread_rng();
let y: f32 = rng.gen(); // generates a float between 0 and 1
let hue: f32 = y * 360.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())
let hue: f32 = rng.gen_interval(0., 360.);
let saturation: f32 = rng.gen_interval(0.9, 1.0);
let value: f32 = rng.gen_interval(0.8, 1.0);
Palette::color(hue, saturation, value)
}
pub fn color(hue: f32, saturation: f32, value: f32) -> Rgb {
Rgb::from_linear(Hsv::new(hue, saturation, value).into_rgb())
}
/// generate a palette from the tint and shade palette
/// algorithm. choose a dark background and a bright filling color
#[allow(dead_code)]
/// algorithm. choose a dark background, and a bright filling color
pub fn bright_on_dark(input: Rgb) -> Palette {
let tint_and_shade_palette = TintAndShadePalette::create(input);
Palette {
@ -43,7 +41,7 @@ impl 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 {
let tint_and_shade_palette = TintAndShadePalette::create(input);
Palette {
@ -54,8 +52,7 @@ impl Palette {
}
/// The Tint and Shade Palette from https://gitlab.com/cameralibre/tint-and-shade
/// Thank you Sam
#[allow(dead_code)]
/// Thank you, Sam
struct TintAndShadePalette {
base_color: Rgb,
base_tint_30: Rgb,

View File

@ -1,3 +1,4 @@
pub(crate) mod merge_ext;
pub(crate) mod random_ext;
pub(crate) mod scale_ext;
pub(crate) mod translate_ext;

View 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.);
}
}
}

View File

@ -3,6 +3,7 @@ pub use crate::context::Context;
mod extensions;
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::translate_ext::TranslateExt;