144 lines
6.0 KiB
Rust
144 lines
6.0 KiB
Rust
use std::io::Write;
|
|
|
|
fn test_file(psd_path: &str, ref_path: &str, out_path: &str, writer: &mut std::io::BufWriter<std::fs::File>) {
|
|
let name = std::path::Path::new(psd_path).file_name().unwrap().to_str().unwrap();
|
|
println!("\n=== {} ===", name);
|
|
writeln!(writer, "=== {} ===", name).unwrap();
|
|
let layers = match hcie_psd::import_psd(std::path::Path::new(psd_path)) {
|
|
Ok(l) => l,
|
|
Err(e) => {
|
|
println!("import_psd failed: {}", e);
|
|
return;
|
|
}
|
|
};
|
|
if layers.is_empty() {
|
|
println!("No layers imported.");
|
|
return;
|
|
}
|
|
|
|
for (i, layer) in layers.iter().enumerate() {
|
|
let effs = if layer.effects.is_empty() { "no effects".to_string() } else {
|
|
let mut parts = Vec::new();
|
|
for e in &layer.effects {
|
|
if let hcie_protocol::effects::LayerEffect::BevelEmboss {
|
|
enabled, style, technique, depth, direction, size, soften,
|
|
angle, altitude, highlight_blend, highlight_color, highlight_opacity,
|
|
shadow_blend, shadow_color, shadow_opacity, ..
|
|
} = e {
|
|
parts.push(format!(
|
|
"BevelEmboss(enabled={}, style={:?}, tech={:?}, depth={}, dir={:?}, size={}, soften={}, angle={}, altitude={}, hl_blend={:?}, hl_color={:?}, hl_op={}, sh_blend={:?}, sh_color={:?}, sh_op={})",
|
|
enabled, style, technique, depth, direction, size, soften,
|
|
angle, altitude, highlight_blend, highlight_color, highlight_opacity, shadow_blend, shadow_color, shadow_opacity
|
|
));
|
|
} else {
|
|
parts.push(format!("{}({})", e.effect_name(), if e.is_enabled() {"on"} else {"off"}));
|
|
}
|
|
}
|
|
format!("{} effects: {}", layer.effects.len(), parts.join(", "))
|
|
};
|
|
println!(" Layer {}: '{}' {}x{} visible={} {}", i, layer.name, layer.width, layer.height, layer.visible, effs);
|
|
}
|
|
|
|
let comp_layers: Vec<hcie_composite::Layer> = layers.iter().map(|l| hcie_composite::Layer {
|
|
name: l.name.clone(),
|
|
layer_type: l.layer_type.clone(),
|
|
data: l.data.clone(),
|
|
pixels: l.pixels.clone(),
|
|
width: l.width,
|
|
height: l.height,
|
|
visible: l.visible,
|
|
opacity: l.opacity,
|
|
blend_mode: l.blend_mode.clone(),
|
|
locked: l.locked,
|
|
dirty: l.dirty,
|
|
id: l.id,
|
|
parent_id: l.parent_id,
|
|
styles: l.styles.clone(),
|
|
clipping_mask: l.clipping_mask,
|
|
collapsed: l.collapsed,
|
|
adjustment: l.adjustment.clone(),
|
|
mask_pixels: l.mask_pixels.clone(),
|
|
mask_bounds: l.mask_bounds,
|
|
mask_default_color: l.mask_default_color,
|
|
curve_points: l.curve_points.clone(),
|
|
fill_opacity: l.fill_opacity,
|
|
effects: l.effects.clone(),
|
|
effects_dirty: std::sync::atomic::AtomicBool::new(false),
|
|
effects_cache: std::sync::Mutex::new(None),
|
|
adjustment_raw: None,
|
|
is_section_divider: false,
|
|
image_resources_raw: None,
|
|
}).collect();
|
|
|
|
let canvas_w = comp_layers[0].width;
|
|
let canvas_h = comp_layers[0].height;
|
|
|
|
let output = hcie_composite::composite_layers(&comp_layers, canvas_w, canvas_h);
|
|
|
|
{
|
|
let orig_img = image::RgbaImage::from_raw(canvas_w, canvas_h, comp_layers[0].pixels.clone())
|
|
.expect("Failed to create orig image from buffer");
|
|
let orig_path = out_path.replace(".png", "_orig.png");
|
|
orig_img.save(orig_path).expect("Failed to save orig image");
|
|
|
|
let img = image::RgbaImage::from_raw(canvas_w, canvas_h, output.clone())
|
|
.expect("Failed to create image from buffer");
|
|
img.save(out_path).expect("Failed to save output image");
|
|
}
|
|
|
|
if std::path::Path::new(ref_path).exists() {
|
|
let ref_img = image::open(ref_path).unwrap().to_rgba8();
|
|
if ref_img.width() == canvas_w && ref_img.height() == canvas_h {
|
|
let mut diff_sum = 0.0f64;
|
|
let mut max_diff = 0u32;
|
|
let comp_img = image::open(out_path).unwrap().to_rgba8();
|
|
for (p1, p2) in comp_img.pixels().zip(ref_img.pixels()) {
|
|
let d = p1.0.iter().zip(p2.0.iter())
|
|
.map(|(a, b)| (*a as i32 - *b as i32).abs() as f64)
|
|
.sum::<f64>();
|
|
diff_sum += d;
|
|
max_diff = max_diff.max(d as u32);
|
|
}
|
|
let px_cnt = (canvas_w * canvas_h) as f64;
|
|
writeln!(writer, " Avg diff per channel: {:.2}", diff_sum / px_cnt).unwrap();
|
|
writeln!(writer, " Max diff per pixel: {}", max_diff).unwrap();
|
|
} else {
|
|
println!("Reference image dimensions differ: ours={}x{} ref={}x{}", canvas_w, canvas_h, ref_img.width(), ref_img.height());
|
|
}
|
|
} else {
|
|
writeln!(writer, " Reference not found: {}", ref_path).unwrap();
|
|
}
|
|
}
|
|
|
|
fn main() {
|
|
use std::fs::File;
|
|
use std::io::BufWriter;
|
|
let out_file = std::env::var("SULTAN_RESULTS_FILE").unwrap_or_else(|_| "sultan_results.txt".to_string());
|
|
let mut writer = BufWriter::new(File::create(out_file).unwrap());
|
|
let base = "_images/_psd_stil_test/sultan_test";
|
|
let sultan_dir = format!("{}/sultan", base);
|
|
|
|
let layers = [
|
|
("Layer 1.psd", "Layer 1.png"),
|
|
("Layer 4.psd", "Layer 4.png"),
|
|
("Layer 3.psd", "Layer 3.png"),
|
|
("Layer 2.psd", "Layer 2.png"),
|
|
];
|
|
|
|
println!("=== Individual Layers ===");
|
|
for (psd_name, ref_name) in &layers {
|
|
let psd = format!("{}/{}", sultan_dir, psd_name);
|
|
let ref_p = if ref_name.is_empty() { String::new() } else { format!("{}/{}", sultan_dir, ref_name) };
|
|
let out = format!("/tmp/sultan_{}.png", ref_name.replace(".png", ""));
|
|
test_file(&psd, &ref_p, &out, &mut writer);
|
|
}
|
|
|
|
println!("\n=== Sultan Composite ===");
|
|
test_file(
|
|
&format!("{}/sultan.psd", base),
|
|
&format!("{}/sultan.png", base),
|
|
"/tmp/sultan_composite.png",
|
|
&mut writer,
|
|
);
|
|
}
|