fast image operations
add blend_alpha_and_color_at function
for blending alpha mask and solid color Co-Authored-By: Kyuuhachig <[email protected]>
bendn 9 months ago
parent 871060a · commit 7fa4f16
-rw-r--r--src/overlay.rs19
-rw-r--r--src/pixels/blending.rs25
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]) {