libeffectengine/effects/
white_noise.rs1use rand::Rng;
2use std::io::Cursor;
3#[cfg(not(target_arch = "wasm32"))]
4use std::process::exit;
5use wasm_bindgen::prelude::*;
6
7use image::{DynamicImage, ImageBuffer, ImageFormat, Rgba};
8
9#[cfg(not(target_arch = "wasm32"))]
10use crate::util::subcommand_help_requested;
11use crate::util::{get_paths, read_image};
12
13#[wasm_bindgen(start)]
14pub fn main_js() {
15 console_error_panic_hook::set_once();
17}
18
19#[wasm_bindgen(js_name = whiteNoise)]
21pub fn effect() -> Vec<u8> {
22 #[cfg(not(target_arch = "wasm32"))]
23 {
24 if subcommand_help_requested() {
25 print_help();
26 exit(0);
27 }
28 }
29
30 let paths = get_paths();
31 let image_data = read_image(paths.input_path);
32
33 let opacity: i32 = std::env::args()
34 .nth(4)
35 .or_else(|| Some(String::from("32")))
36 .unwrap()
37 .parse()
38 .unwrap_or_else(|_| 32);
39
40 let opacity_factor = opacity as f32 / 255.0;
41
42 let img =
43 image::load_from_memory(&image_data.data).expect("Failed to decode image from memory");
44 let image = img.to_rgba8();
45 let mut new_image = ImageBuffer::new(image.width(), image.height());
46
47 for x in 0..image.width() {
48 for y in 0..image.height() {
49 let pixel = image.get_pixel(x, y);
50 let noise_value = rand::rng().random_range(0..255);
51
52 let r = (pixel.0[0] as f32
53 + (1.0 - opacity_factor)
54 + noise_value as f32 * opacity_factor) as u8;
55 let g = (pixel.0[1] as f32
56 + (1.0 - opacity_factor)
57 + noise_value as f32 * opacity_factor) as u8;
58 let b = (pixel.0[2] as f32
59 + (1.0 - opacity_factor)
60 + noise_value as f32 * opacity_factor) as u8;
61 let a = (pixel.0[3] as f32
62 + (1.0 - opacity_factor)
63 + noise_value as f32 * opacity_factor) as u8;
64
65 new_image.put_pixel(x, y, Rgba([r, g, b, a]));
66 }
67 }
68
69 let mut cursor = Cursor::new(Vec::new());
70
71 if image_data.format == ImageFormat::Jpeg {
72 let rgb_image = DynamicImage::ImageRgba8(new_image).into_rgb8();
73 rgb_image
74 .write_to(&mut cursor, image_data.format)
75 .expect("Failed to encode JPEG");
76 } else {
77 new_image
78 .write_to(&mut cursor, image_data.format)
79 .expect("Failed to encode image");
80 }
81
82 return cursor.into_inner();
83}
84
85#[cfg(not(target_arch = "wasm32"))]
87fn print_help() {
88 println!(
89 r#"
90White Noise Effect
91Overlays an image with white noise at a given opacity.
92
93USAGE:
94 effectengine white-noise <INPUT_PATH> <OUTPUT_PATH> [OPACITY]
95
96ARGUMENTS:
97 <INPUT_PATH> The path to an input image that should be processed.
98 <OUTPUT_PATH> The path where the resulting image should be saved.
99 Needs to include the filename.
100 <OPACITY> The opacity of the overlaid noise. A number between 0 and
101 255. (Default: 32)
102 "#
103 );
104}