fast image operations
add blend_alpha_and_color_at function
for blending alpha mask and solid color
Co-Authored-By: Kyuuhachig <[email protected]>
| -rw-r--r-- | src/overlay.rs | 19 | ||||
| -rw-r--r-- | src/pixels/blending.rs | 25 |
2 files changed, 43 insertions, 1 deletions
diff --git a/src/overlay.rs b/src/overlay.rs index b21985d..f2bf0e6 100644 --- a/src/overlay.rs +++ b/src/overlay.rs @@ -163,6 +163,25 @@ where } } +impl<T: AsMut<[u8]> + AsRef<[u8]>> Image<T, 3> { + #[doc(hidden)] + pub unsafe fn blend_alpha_and_color_at( + &mut self, + with: &Image<&[u8], 1>, + color: [u8; 3], + x: u32, + y: u32, + ) { + for j in 0..with.height() { + for i in 0..with.width() { + let &[their_alpha] = unsafe { &with.pixel(i, j) }; + let our_pixel = unsafe { self.pixel_mut(i + x, j + y) }; + crate::pixels::blending::blend_alpha_and_color(their_alpha, color, our_pixel); + } + } + } +} + impl ClonerOverlay<4, 4> for ImageCloner<'_, 4> { #[inline] #[must_use = "function does not modify the original image"] diff --git a/src/pixels/blending.rs b/src/pixels/blending.rs index 20d312e..33beecf 100644 --- a/src/pixels/blending.rs +++ b/src/pixels/blending.rs @@ -1,6 +1,6 @@ //! module for pixel blending ops #![allow(redundant_semicolons)] -use super::{Floatify, Unfloatify, convert::PFrom, unfloat}; +use super::{Floatify, Unfloatify, convert::PFrom, float, unfloat}; use atools::prelude::*; /// Trait for blending pixels together. @@ -9,6 +9,29 @@ pub trait Blend<const W: usize> { fn blend(&mut self, with: [u8; W]); } +pub(crate) fn blend_alpha_and_color(a: u8, color: [u8; 3], onto: &mut [u8; 3]) { + if a == 0 { + return; + } + if a == 255 { + *onto = color; + return; + } + + let [br, bg, bb] = *onto; + let [fr, fg, fb] = color; + + onto[0] = lerp(br, fr, a); + onto[1] = lerp(bg, fg, a); + onto[2] = lerp(bb, fb, a); + + // onto.copy_from_slice(&fg.zip(bg).map(|(f, b)| a * (f - b) + b)); +} + +fn lerp(ba: u8, fo: u8, a: u8) -> u8 { + ((fo as i32 - ba as i32) * a as i32 / 256 + ba as i32) as u8 +} + impl Blend<4> for [u8; 4] { #[lower::apply(algebraic)] fn blend(&mut self, fg: [u8; 4]) { |