extern crate image;
use image::{GenericImage, GenericImageView};
use crate::{PhotonImage};
use crate::helpers;
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
pub fn monochrome(mut photon_image: &mut PhotonImage, r_offset: u32, g_offset: u32, b_offset: u32) {
let mut img = helpers::dyn_image_from_raw(&photon_image);
let (width, height) = img.dimensions();
for x in 0..width {
for y in 0..height {
let px = img.get_pixel(x, y);
let (r_val, g_val, b_val) = (px.data[0] as u32, px.data[1] as u32, px.data[2] as u32);
let mut avg = (r_val + g_val + b_val) / 3;
if avg >= 255 {
avg = 255
}
let new_r = if avg as u32 + r_offset < 255 { avg as u8 + r_offset as u8} else { 255 };
let new_g = if avg as u32 + g_offset < 255 { avg as u8 + g_offset as u8} else { 255 };
let new_b = if avg as u32 + b_offset < 255 { avg as u8 + b_offset as u8} else { 255 };
img.put_pixel(x, y, image::Rgba([new_r, new_g, new_b, 255]));
}
}
let raw_pixels = img.raw_pixels();
photon_image.raw_pixels = raw_pixels;
}
#[wasm_bindgen]
pub fn sepia(mut photon_image: &mut PhotonImage) {
let mut img = helpers::dyn_image_from_raw(&photon_image);
let (width, height) = img.dimensions();
for x in 0..width {
for y in 0..height {
let px = img.get_pixel(x, y);
let (r_val, g_val, b_val) = (px.data[0] as f32, px.data[1] as f32, px.data[2] as f32);
let avg = 0.3 * r_val + 0.59 * g_val + 0.11 * b_val;
let new_r = if avg as u32 + 100 < 255 { avg as u8 + 100} else { 255 };
let new_g = if avg as u32 + 50 < 255 { avg as u8 + 50 } else { 255 };
img.put_pixel(x, y, image::Rgba([new_r, new_g, b_val as u8, 255]));
}
}
let raw_pixels = img.raw_pixels();
photon_image.raw_pixels = raw_pixels;
}
#[wasm_bindgen]
pub fn grayscale(mut photon_image: &mut PhotonImage) {
let mut img = helpers::dyn_image_from_raw(&photon_image);
let (width, height) = img.dimensions();
for x in 0..width {
for y in 0..height {
let px = img.get_pixel(x, y);
let (r_val, g_val, b_val) = (px.data[0] as u32, px.data[1] as u32, px.data[2] as u32);
let mut avg = ((r_val + g_val + b_val) / 3) as u8;
if avg >= 255 {
avg = 255
}
img.put_pixel(x, y, image::Rgba([avg, avg, avg, 255]));
}
}
let raw_pixels = img.raw_pixels();
photon_image.raw_pixels = raw_pixels;
}
#[wasm_bindgen]
pub fn grayscale_human_corrected(mut photon_image: &mut PhotonImage) {
let mut img = helpers::dyn_image_from_raw(&photon_image);
let (width, height) = img.dimensions();
for x in 0..width {
for y in 0..height {
let px = img.get_pixel(x, y);
let (r_val, g_val, b_val) = (px.data[0] as f32, px.data[1] as f32, px.data[2] as f32);
let mut avg: u8 = (r_val * 0.3 + g_val * 0.59 + b_val * 0.11) as u8;
if avg >= 255 {
avg = 255
}
img.put_pixel(x, y, image::Rgba([avg, avg, avg, 255]));
}
}
let raw_pixels = img.raw_pixels();
photon_image.raw_pixels = raw_pixels;
}
#[wasm_bindgen]
pub fn desaturate(mut photon_image: &mut PhotonImage) {
let mut img = helpers::dyn_image_from_raw(&photon_image);
let (width, height) = img.dimensions();
for x in 0..width {
for y in 0..height {
let px = img.get_pixel(x, y);
let (r_val, g_val, b_val) = (px.data[0] as u32, px.data[1] as u32, px.data[2] as u32);
let mut rgb_vals = vec![r_val, g_val, b_val];
rgb_vals.sort();
let mut gray = ((rgb_vals[0] + rgb_vals[2]) / 2) as u8;
if gray >= 255 {
gray = 255
}
img.put_pixel(x, y, image::Rgba([gray, gray, gray, 255]));
}
}
let raw_pixels = img.raw_pixels();
photon_image.raw_pixels = raw_pixels;
}
#[wasm_bindgen]
pub fn decompose_min(mut photon_image: &mut PhotonImage) {
let mut img = helpers::dyn_image_from_raw(&photon_image);
let (width, height) = img.dimensions();
for x in 0..width {
for y in 0..height {
let px = img.get_pixel(x, y);
let (r_val, g_val, b_val) = (px.data[0] as u32, px.data[1] as u32, px.data[2] as u32);
let mut rgb_vals = vec![r_val, g_val, b_val];
rgb_vals.sort();
let mut gray = rgb_vals[0] as u8;
if gray >= 255 {
gray = 255
}
img.put_pixel(x, y, image::Rgba([gray, gray, gray, 255]));
}
}
let raw_pixels = img.raw_pixels();
photon_image.raw_pixels = raw_pixels;
}
#[wasm_bindgen]
pub fn decompose_max(mut photon_image: &mut PhotonImage) {
let mut img = helpers::dyn_image_from_raw(&photon_image);
let (width, height) = img.dimensions();
for x in 0..width {
for y in 0..height {
let px = img.get_pixel(x, y);
let (r_val, g_val, b_val) = (px.data[0] as u32, px.data[1] as u32, px.data[2] as u32);
let mut rgb_vals = vec![r_val, g_val, b_val];
rgb_vals.sort();
let gray = rgb_vals[2] as u8;
img.put_pixel(x, y, image::Rgba([gray, gray, gray, 255]));
}
}
let raw_pixels = img.raw_pixels();
photon_image.raw_pixels = raw_pixels;
}
#[wasm_bindgen]
pub fn grayscale_shades(mut photon_image: &mut PhotonImage, num_shades: u8) {
let mut img = helpers::dyn_image_from_raw(&photon_image);
let (width, height) = img.dimensions();
for x in 0..width {
for y in 0..height {
let px = img.get_pixel(x, y);
let conversion: f32 = 255.0 / (num_shades as f32 - 1.0);
let (r_val, g_val, b_val) = (px.data[0] as u32, px.data[1] as u32, px.data[2] as u32);
let avg: f32 = (r_val + g_val + b_val) as f32 / 3.0;
let dividend = avg / conversion as f32;
let gray = ((dividend + 0.5) * conversion) as u8;
img.put_pixel(x, y, image::Rgba([gray, gray, gray, 255]));
}
}
let raw_pixels = img.raw_pixels();
photon_image.raw_pixels = raw_pixels;
}
#[wasm_bindgen]
pub fn r_grayscale(photon_image: &mut PhotonImage) {
return single_channel_grayscale(photon_image, 0)
}
#[wasm_bindgen]
pub fn g_grayscale(photon_image: &mut PhotonImage) {
return single_channel_grayscale(photon_image, 1)
}
#[wasm_bindgen]
pub fn b_grayscale(photon_image: &mut PhotonImage) {
return single_channel_grayscale(photon_image, 2)
}
#[wasm_bindgen]
pub fn single_channel_grayscale(mut photon_image: &mut PhotonImage, channel: usize) {
let mut img = helpers::dyn_image_from_raw(&photon_image);
let (width, height) = img.dimensions();
for x in 0..width {
for y in 0..height {
let mut px = img.get_pixel(x, y);
let channel_data = px.data[channel];
px.data[0] = channel_data as u8;
px.data[1] = channel_data as u8;
px.data[2] = channel_data as u8;
img.put_pixel(x, y, px);
}
}
let raw_pixels = img.raw_pixels();
photon_image.raw_pixels = raw_pixels;
}
#[wasm_bindgen]
pub fn threshold(mut photon_image: &mut PhotonImage, threshold: u32) {
let mut img = helpers::dyn_image_from_raw(&photon_image);
let (width, height) = img.dimensions();
for x in 0..width {
for y in 0..height {
let mut px = img.get_pixel(x, y);
let r: f32 = px.data[0].into();
let g: f32 = px.data[1].into();
let b: f32 = px.data[2].into();
let mut v = 0.2126 * r + 0.7152 * g + 0.072 * b;
if v >= threshold as f32 {
v = 255.0;
}
else {
v = 0.0;
}
px.data[0] = v as u8;
px.data[1] = v as u8;
px.data[2] = v as u8;
img.put_pixel(x, y, px);
}
}
let raw_pixels = img.raw_pixels();
photon_image.raw_pixels = raw_pixels;
}