Files
hcie-rust-v3.05/hcie-io/examples/tune_mae_satin.rs

96 lines
4.3 KiB
Rust

use std::io::Write;
const RESULTS_FILE: &str = "/mnt/extra/00_PROJECTS/hcie-rust-v4/satin_results.txt";
fn main() {
let psd_path = "_images/_psd_stil_test/satin.psd";
let ref_path = "_images/_psd_stil_test/satin.png";
let ref_img = image::open(ref_path).expect("open satin.png").to_rgba8();
let (w, h) = (ref_img.width(), ref_img.height());
let px = (w * h) as usize;
let ref_pixels = ref_img.into_raw();
let layers = hcie_psd::import_psd(std::path::Path::new(psd_path)).expect("import satin.psd");
let layer = &layers[0];
let alpha: Vec<u8> = layer.pixels.iter().skip(3).step_by(4).copied().collect();
let (angle, distance, size, color, blend_mode_str, opacity, invert) = {
let mut ang = 0.0f32; let mut dist = 0.0f32; let mut sz = 0.0f32;
let mut col = [0u8; 4]; let mut bm = String::new(); let mut op = 0.0f32; let mut inv = false;
for e in &layer.effects {
if let hcie_protocol::effects::LayerEffect::Satin { enabled: true, angle, distance, size, color, blend_mode, opacity, invert, .. } = e {
ang = *angle; dist = *distance; sz = *size; col = *color; bm = blend_mode.clone(); op = *opacity; inv = *invert;
}
}
(ang, dist, sz, col, bm, op, inv)
};
let bm_parsed = hcie_fx::types::blend_mode_from_string(&blend_mode_str);
println!("Satin: angle={}, distance={}, size={}, color={:?}, blend={}, opacity={}, invert={}", angle, distance, size, color, blend_mode_str, opacity, invert);
println!("Image: {}x{}", w, h);
std::io::stdout().flush().ok();
let mut best_mae = f64::MAX;
let mut best_params = (0.0f32, 0i32, 0.0f32);
let blur_factors = &[0.5, 0.75, 1.0, 1.25, 1.5, 2.0, 2.5, 3.0, 4.0, 5.0, 6.0, 8.0, 10.0];
let passes_list = &[1, 2, 3, 4, 5, 6, 8, 10];
let intersect_strengths = &[0.25, 0.5, 0.75, 1.0, 1.25, 1.5, 2.0];
let total = blur_factors.len() * passes_list.len() * intersect_strengths.len();
println!("Grid search: {} combos", total);
std::io::stdout().flush().ok();
let mut count = 0usize;
for blur_factor in blur_factors {
for passes in passes_list {
for intersect_strength in intersect_strengths {
count += 1;
if count % 200 == 0 {
println!(" [{}/{}] best={:.3}", count, total, best_mae);
std::io::stdout().flush().ok();
}
let satin = hcie_fx::tuned::generate_satin_tuned(
&alpha, w, h, angle, distance, size, color, invert,
*blur_factor, *passes, *intersect_strength,
);
let mut out = layer.pixels.clone();
for i in 0..px {
let sa = satin[i * 4 + 3];
if sa == 0 { continue; }
let dst = [out[i * 4], out[i * 4 + 1], out[i * 4 + 2], out[i * 4 + 3]];
let src = [satin[i * 4], satin[i * 4 + 1], satin[i * 4 + 2], sa];
let blended = hcie_blend::blend_pixels(dst, src, bm_parsed, opacity);
out[i * 4..i * 4 + 4].copy_from_slice(&blended);
}
let mut diff_sum = 0.0f64;
for i in 0..px {
let d = (0..4).map(|c| (out[i * 4 + c] as i32 - ref_pixels[i * 4 + c] as i32).abs() as f64).sum::<f64>();
diff_sum += d;
}
let mae = diff_sum / px as f64 / 4.0;
if mae < best_mae {
best_mae = mae;
best_params = (*blur_factor, *passes, *intersect_strength);
println!("*** NEW BEST: {:.3} (blur_factor={:.1}, passes={}, intersect_strength={:.2})",
best_mae, blur_factor, passes, intersect_strength);
std::io::stdout().flush().ok();
}
}
}
}
if best_mae < f64::MAX {
let (bbf, bp, bis) = best_params;
println!("\nBest MAE = {:.3} (blur_factor={:.1}, passes={}, intersect_strength={:.2})", best_mae, bbf, bp, bis);
if let Ok(mut file) = std::fs::OpenOptions::new().create(true).write(true).truncate(true).open(RESULTS_FILE) {
let _ = writeln!(file, "=== Satin Tuned ===\n Params: blur_factor={:.1}, passes={}, intersect_strength={:.2}\n MAE: {:.3}", bbf, bp, bis, best_mae);
}
}
}