Files
vectorcraft/crates/effects/src/pixel/sharpen.rs
T
bflatasticandClaude Opus 5.5 1e7f5084d8 Part of ROADMAP gap 2: Radial Blur, Smart Blur and Unsharp Mask on a pixel-filter pipeline
Effect › Blur › Radial Blur (spin/zoom, draft/good/best) and Smart Blur
(Normal mode), Effect › Sharpen › Unsharp Mask: Photoshop-style filters in
vectorcraft_effects::pixel, run by the renderer on the object's pixels in
stack order with Gaussian Blur and Feather, cached while panning; lengths in
points, bounded work per pixel. PDF, Expand Appearance and SVG export write
the effected objects as images. Dialogs with preview (method/quality
dropdowns, fields in documented order), menu entries, translations, tests.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-09 13:30:31 +07:00

32 lines
1.2 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//! Sharpen › Unsharp Mask.
use super::{gaussian, to16};
/// Unsharp Mask: each colour channel pushed away from a Gaussian blur of the pixels (σ = `sigma`
/// pixels) by `amount` times their difference, where that difference reaches `threshold` levels.
/// The blur is premultiplied, so edges against transparency don't darken; coverage stays as it is.
pub(super) fn unsharp(px: &mut [[u8; 4]], w: usize, h: usize, amount: f64, sigma: f64, threshold: f64) {
if sigma.is_nan() || sigma < 0.2 || amount.is_nan() || amount <= 0.0 || h == 0 {
return;
}
let mut blurred = to16(px);
gaussian(&mut blurred, w, sigma);
let (amount, threshold) = (amount as f32, threshold as f32);
for (p, b) in px.iter_mut().zip(&blurred) {
let a = p[3] as f32;
if a == 0.0 {
continue;
}
for i in 0..3 {
let own = p[i] as f32 * 255.0 / a;
let around = if b[3] > 0 { b[i] as f32 * 255.0 / b[3] as f32 } else { own };
let diff = own - around;
if diff.abs() < threshold || diff == 0.0 {
continue;
}
let v = (own + amount * diff).clamp(0.0, 255.0);
p[i] = (v * a / 255.0).round().clamp(0.0, 255.0) as u8;
}
}
}