Implement alpha premultiplication (#507)

* Implement alpha premultiplication

* Add benchmark to resize

* Only display "Premultiply alpha" if it's one of the rust resize types.

* Add comment about division by zero
This commit is contained in:
Surma
2019-03-08 11:18:59 +00:00
committed by Jake Archibald
parent d29cf2ffa7
commit 45221c0b03
12 changed files with 127 additions and 35 deletions

View File

@@ -22,12 +22,13 @@ cfg_if! {
#[wasm_bindgen]
#[no_mangle]
pub fn resize(
input_image: Vec<u8>,
mut input_image: Vec<u8>,
input_width: usize,
input_height: usize,
output_width: usize,
output_height: usize,
typ_idx: usize,
premultiply: bool,
) -> Vec<u8> {
let typ = match typ_idx {
0 => Type::Triangle,
@@ -36,7 +37,19 @@ pub fn resize(
3 => Type::Lanczos3,
_ => panic!("Nope"),
};
let num_input_pixels = input_width * input_height;
let num_output_pixels = output_width * output_height;
if premultiply {
for i in 0..num_input_pixels {
for j in 0..3 {
input_image[4 * i + j] = ((input_image[4 * i + j] as f32)
* (input_image[4 * i + 3] as f32)
/ 255.0) as u8;
}
}
}
let mut resizer = resize::new(
input_width,
input_height,
@@ -48,5 +61,19 @@ pub fn resize(
let mut output_image = Vec::<u8>::with_capacity(num_output_pixels * 4);
output_image.resize(num_output_pixels * 4, 0);
resizer.resize(input_image.as_slice(), output_image.as_mut_slice());
if premultiply {
for i in 0..num_output_pixels {
for j in 0..3 {
// We dont need to worry about division by zero, as division by zero
// is well-defined on floats to return `±Inf`. ±Inf is converted to 0
// when casting to integers.
output_image[4 * i + j] = ((output_image[4 * i + j] as f32) * 255.0
/ (output_image[4 * i + 3] as f32))
as u8;
}
}
}
return output_image;
}