update calculate_dimensions() logic to work with glyph bitmaps and maintain correct aspect ratio

This commit is contained in:
Waveplate 2025-05-15 20:39:52 -07:00
parent d50e8fab0c
commit c1ba3e91e3

View File

@ -1,49 +1,71 @@
use crate::args; use crate::args;
use crate::chars::GLYPH_BITMAPS;
use photon_rs::{colour_spaces, channels, conv, effects, filters, monochrome, noise}; use photon_rs::{colour_spaces, channels, conv, effects, filters, monochrome, noise};
use photon_rs::transform::{SamplingFilter, resize, crop, rotate, flipv, fliph}; use photon_rs::transform::{SamplingFilter, resize, crop, rotate, flipv, fliph};
use photon_rs::PhotonImage; use photon_rs::PhotonImage;
fn calculate_dimensions(args: &args::Args, image: &PhotonImage) -> (u32, u32) { fn calculate_dimensions(args: &args::Args, image: &PhotonImage) -> (u32, u32) {
let original_width = image.get_width() as f32; let orig_w = image.get_width() as f32;
let original_height = image.get_height() as f32; let orig_h = image.get_height() as f32;
let original_aspect = original_width / original_height;
let base_width; // determine percell pixel factor:
let base_height; // braille cells cover 2×4 pixels; block cells use glyph bitmap size
let (factor_x, factor_y) = if args.braille {
let aspect_ratio = if let Some(aspect) = args.aspect { (2.0, 4.0)
aspect.0 / aspect.1
} else { } else {
original_aspect let glyph = &GLYPH_BITMAPS[0].1;
(glyph[0].len() as f32, glyph.len() as f32)
}; };
if args.width.is_none() && args.height.is_none() { let (mut pw, mut ph) = match (args.width, args.height) {
base_width = original_width; (Some(wc), Some(hc)) => (
base_height = original_height; wc as f32 * factor_x,
} else if args.width.is_none() { hc as f32 * factor_y,
let provided_height = args.height.unwrap(); ),
base_height = provided_height as f32;
base_width = base_height * aspect_ratio; // only width in characters → width*factor_x pixels, height by original aspect
} else if args.height.is_none() { (Some(wc), None) => {
let provided_width = args.width.unwrap(); let pw = wc as f32 * factor_x;
base_width = provided_width as f32; let ph = pw * (orig_h / orig_w);
base_height = base_width / aspect_ratio; (pw, ph)
} else {
base_width = args.width.unwrap() as f32;
base_height = args.height.unwrap() as f32;
} }
let (scaled_width, scaled_height) = if let Some(scale) = args.scale { // only height in characters → height*factor_y pixels, width by original aspect
(base_width * scale.0, base_height * scale.1) (None, Some(hc)) => {
} else { let ph = hc as f32 * factor_y;
(base_width, base_height) let pw = ph * (orig_w / orig_h);
(pw, ph)
}
// neither specified → keep original pixel dimensions
(None, None) => (orig_w, orig_h),
}; };
// Step 4: Round the scaled dimensions to the nearest integer and ensure a minimum size of 1. if let Some((sx, sy)) = args.scale {
let final_width = scaled_width.round().max(1.0) as u32; pw *= sx;
let final_height = scaled_height.round().max(1.0) as u32; ph *= sy;
}
(final_width, final_height) // braille aspect tweak: if only one dimension was specified,
// shrink the other by 10% to compensate cell shape
if args.braille {
match (args.width.is_some(), args.height.is_some()) {
(true, false) => {
// width fixed → reduce height
ph *= 0.9;
}
(false, true) => {
// height fixed → reduce width
pw *= 1.11;
}
_ => {}
}
}
let out_w = pw.round().max(1.0) as u32;
let out_h = ph.round().max(1.0) as u32;
(out_w, out_h)
} }
pub fn apply_effects( pub fn apply_effects(