aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main.rs1
-rw-r--r--src/render.rs79
2 files changed, 70 insertions, 10 deletions
diff --git a/src/main.rs b/src/main.rs
index b241eb5..5de9d56 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -5,6 +5,7 @@ extern crate imageproc;
extern crate itertools;
extern crate md5;
extern crate num_enum;
+extern crate num_traits;
extern crate reqwest;
extern crate rusttype;
extern crate termcolor;
diff --git a/src/render.rs b/src/render.rs
index 437b66c..51f4ceb 100644
--- a/src/render.rs
+++ b/src/render.rs
@@ -1,7 +1,11 @@
use super::api::{Api, ApiError, Skill, Specialization, Trait};
use super::bt::{BuildTemplate, TraitChoice, Traitline};
-use image::{imageops, DynamicImage, GenericImage, GenericImageView, ImageBuffer, Rgba, RgbaImage};
+use image::{
+ imageops, CatmullRom, DynamicImage, GenericImage, GenericImageView, ImageBuffer, Pixel,
+ Primitive, Rgba, RgbaImage,
+};
use imageproc::drawing::{self, Point};
+use num_traits::NumCast;
use rusttype::{Font, Scale, SharedBytes};
quick_error! {
@@ -24,6 +28,8 @@ pub struct RenderOptions {
traitline_height: u32,
traitline_width: u32,
traitline_brightness: i32,
+ traitline_use_gradient: bool,
+ traitline_gradient_size: u32,
traitline_x_offset: u32,
trait_size: u32,
line_color: Rgba<u8>,
@@ -43,6 +49,8 @@ impl Default for RenderOptions {
traitline_height: 137,
traitline_width: 647,
traitline_brightness: 100,
+ traitline_use_gradient: true,
+ traitline_gradient_size: 50,
traitline_x_offset: 200,
trait_size: 30,
line_color: Rgba([0, 0, 0, 255]),
@@ -78,11 +86,7 @@ impl<'r> Renderer<'r> {
pub fn new(api: &mut Api, options: RenderOptions) -> Renderer<'_> {
let minor_mask = image::load_from_memory(include_bytes!("minor_trait_mask.png"))
.expect("Mask image could not be loaded")
- .resize(
- options.trait_size,
- options.trait_size,
- imageops::FilterType::CatmullRom,
- );
+ .resize(options.trait_size, options.trait_size, CatmullRom);
Renderer {
api,
options,
@@ -100,7 +104,7 @@ impl<'r> Renderer<'r> {
let img = self.api.get_image(&skill.icon)?.resize(
self.options.skill_size,
self.options.skill_size,
- imageops::FilterType::CatmullRom,
+ CatmullRom,
);
buffer.copy_from(&img, i as u32 * self.options.skill_size, 0);
}
@@ -116,7 +120,7 @@ impl<'r> Renderer<'r> {
let minor_img = self.api.get_image(&minor.icon)?.resize(
self.options.trait_size,
self.options.trait_size,
- imageops::FilterType::CatmullRom,
+ CatmullRom,
);
let minor_img = with_mask(&minor_img, &self.minor_mask);
let y_pos = (buffer.height() - minor_img.height()) / 2;
@@ -138,7 +142,7 @@ impl<'r> Renderer<'r> {
let major_img = self.api.get_image(&major.icon)?.resize(
self.options.trait_size,
self.options.trait_size,
- imageops::FilterType::CatmullRom,
+ CatmullRom,
);
let major_img = if !chosen {
with_mask(&major_img.grayscale(), &major_img)
@@ -225,7 +229,6 @@ impl<'r> Renderer<'r> {
BG_CROP_WIDTH,
BG_CROP_HEIGHT,
)
- .brighten(self.options.traitline_brightness)
.resize(
self.options.traitline_width,
self.options.traitline_height,
@@ -233,6 +236,17 @@ impl<'r> Renderer<'r> {
)
.to_rgba();
+ if self.options.traitline_use_gradient {
+ buffer = brighten_gradient(
+ &buffer,
+ self.options.traitline_x_offset - self.options.traitline_gradient_size,
+ self.options.traitline_x_offset,
+ self.options.traitline_brightness,
+ );
+ } else {
+ buffer = imageops::colorops::brighten(&buffer, self.options.traitline_brightness);
+ }
+
let minor_traits = self.api.get_traits(&spec.minor_traits)?;
for minor in &minor_traits {
self.render_minor_trait(&mut buffer, &minor)?;
@@ -337,3 +351,48 @@ where
Rgba([p[0], p[1], p[2], alpha])
})
}
+
+fn brighten_gradient<I, P, S>(
+ image: &I,
+ start_x: u32,
+ end_x: u32,
+ value: i32,
+) -> ImageBuffer<P, Vec<S>>
+where
+ I: GenericImageView<Pixel = P>,
+ P: Pixel<Subpixel = S> + 'static,
+ S: Primitive + 'static,
+{
+ use image::math::utils::clamp;
+ let (width, height) = image.dimensions();
+ let mut out = ImageBuffer::new(width, height);
+
+ let max = S::max_value();
+ let max: i32 = NumCast::from(max).unwrap();
+
+ for y in 0..height {
+ for x in 0..width {
+ let e = image.get_pixel(x, y).map_with_alpha(
+ |b| {
+ let interpol_value = if x < start_x {
+ 0
+ } else if x > end_x {
+ value
+ } else {
+ let frac = (x - start_x) as f32 / (end_x - start_x) as f32;
+ (frac * value as f32).round() as i32
+ };
+ let c: i32 = NumCast::from(b).unwrap();
+ let d = clamp(c + interpol_value, 0, max);
+
+ NumCast::from(d).unwrap()
+ },
+ |alpha| alpha,
+ );
+
+ out.put_pixel(x, y, e);
+ }
+ }
+
+ out
+}