[web] Added procedural color generation
This commit is contained in:
parent
3530038ca4
commit
97bc7feea6
72
web/src/contrast.rs
Normal file
72
web/src/contrast.rs
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
#![cfg(feature = "ogp_images")]
|
||||
|
||||
use image::{Pixel, Rgb, Rgba};
|
||||
use pronouns_today::util::pcg64;
|
||||
|
||||
pub fn generate_color_pair(state: &mut u128) -> ([u8; 3], [u8; 3]) {
|
||||
let mut background = random_color(state);
|
||||
let mut foreground;
|
||||
loop {
|
||||
foreground = random_color(state);
|
||||
if meets_criteria(&foreground, &background) {
|
||||
break;
|
||||
}
|
||||
background = random_color(state);
|
||||
if meets_criteria(&foreground, &background) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
(foreground, background)
|
||||
}
|
||||
|
||||
pub fn generate_color_pair_rgba(state: &mut u128) -> (Rgba<u8>, Rgba<u8>) {
|
||||
let (color1, color2) = generate_color_pair(state);
|
||||
|
||||
let (color1, color2): (Rgb<u8>, Rgb<u8>) = (
|
||||
color1.into(),
|
||||
color2.into(),
|
||||
);
|
||||
|
||||
(color1.to_rgba(), color2.to_rgba())
|
||||
}
|
||||
|
||||
pub fn relative_lum(color: &[u8; 3]) -> f32 {
|
||||
let color_mapped: Vec<f32> = color.iter()
|
||||
.map(|val| {
|
||||
let val = *val as f32 / 255.0;
|
||||
if val < 0.03928 {
|
||||
val / 12.92
|
||||
} else {
|
||||
((val+0.055)/1.055).powf(2.4)
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
return 0.2126 * color_mapped[0] + 0.7152 * color_mapped[1] + 0.0722 * color_mapped[2]
|
||||
}
|
||||
|
||||
pub fn check_contrast(color1: &[u8; 3], color2: &[u8; 3]) -> f32 {
|
||||
let a = 0.05 + relative_lum(color1);
|
||||
let b = 0.05 + relative_lum(color2);
|
||||
(a / b).max(b / a)
|
||||
}
|
||||
|
||||
pub fn get_saturation(color: &[u8; 3]) -> f32 {
|
||||
let chroma_max = *(color.iter().max().unwrap());
|
||||
let chroma_min = *(color.iter().min().unwrap());
|
||||
return ((chroma_max - chroma_min) as f32) / chroma_max as f32;
|
||||
}
|
||||
|
||||
pub fn random_color(state: &mut u128) -> [u8; 3] {
|
||||
let random = pcg64(state).to_le_bytes();
|
||||
return [
|
||||
random[0],
|
||||
random[1],
|
||||
random[2],
|
||||
]
|
||||
}
|
||||
|
||||
pub fn meets_criteria(foreground: &[u8; 3], background: &[u8; 3]) -> bool {
|
||||
return check_contrast(foreground, background) >= 5.0 &&
|
||||
get_saturation(background) < 0.65 &&
|
||||
get_saturation(foreground) < 0.65
|
||||
}
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
pub mod ogp_images;
|
||||
pub mod contrast;
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::fmt::{self, Display};
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
#![cfg(feature = "ogp_images")]
|
||||
|
||||
use crate::contrast::generate_color_pair_rgba;
|
||||
|
||||
use image::{DynamicImage, ImageBuffer, Pixel, Rgb, Rgba};
|
||||
use lazy_static::lazy_static;
|
||||
use pronouns_today::Pronoun;
|
||||
use pronouns_today::{Pronoun, util::{self, pcg64_seed, seed_with_today}};
|
||||
use rusttype::{Font, Scale, point};
|
||||
|
||||
const SCALE: u32 = 400;
|
||||
|
|
@ -13,9 +15,16 @@ lazy_static! {
|
|||
.expect("Invalid font data in build. This build and binary is invalid, and cannot be used.");
|
||||
}
|
||||
|
||||
pub fn render(pronouns: &Pronoun) -> ImageBuffer<Rgb<u8>, Vec<u8>> {
|
||||
// TODO: Use a real seed here
|
||||
let (color1, color2) = generate_color_pair(&[13, 12]);
|
||||
pub fn render_today(pronouns: &Pronoun, name: &str) -> ImageBuffer<Rgb<u8>, Vec<u8>> {
|
||||
let mut state = util::INITIAL_STATE;
|
||||
|
||||
seed_with_today(&mut state);
|
||||
pcg64_seed(&mut state, name.as_bytes());
|
||||
|
||||
render(pronouns, &mut state)
|
||||
}
|
||||
pub fn render(pronouns: &Pronoun, pcg64: &mut u128) -> ImageBuffer<Rgb<u8>, Vec<u8>> {
|
||||
let (color1, color2) = generate_color_pair_rgba(pcg64);
|
||||
|
||||
render_with_colors(pronouns, color1, color2)
|
||||
}
|
||||
|
|
@ -74,7 +83,3 @@ pub fn render_with_colors(pronouns: &Pronoun, color1: Rgba<u8>, color2: Rgba<u8>
|
|||
|
||||
image::DynamicImage::ImageRgba8(output_image).into_rgb8()
|
||||
}
|
||||
|
||||
pub fn generate_color_pair(seed: &[u8]) -> (Rgba<u8>, Rgba<u8>) {
|
||||
todo!();
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue